I'm using the latest ionic with the slides, which i believe uses Swiper.
I have the swiper options like this:
{
initialSlide: 0,
speed: 400,
onInit: (slides: any) => {
console.log("SLIDE INIT",slides)
this.slider = slides
}
However nothing happens, as though onInit doesn't fire. I have also tried "init" based on the swiper documentation and that also doesn't fire.
What i am trying to do is set the slider to this.slider so i can use the api on it later.
do something like:
import { Component, OnInit, ViewChild, ElementRef, NgZone } from '#angular/core';
import { IonSlides } from '#ionic/angular';
export class YourClass implements OnInit {
#ViewChild('slides') slides: IonSlides;
console.log(this.slides); // Now you can access your slide in this.slides
}
in html:
<ion-slides pager="true" [options]="sliderConfig" #slides>
...
</ion-slides>
Related
in Ionic I managed to make a program with the tts plugin that reproduces the text that I write in an input, but so far I have not been able to implement a button that stops the audio that is played, I would appreciate a lot if you help me.
How do I make a class that stops the audio?
This is my .ts file:
import { Component, OnInit } from '#angular/core';
import { TextToSpeech } from '#ionic-native/text-to-speech/ngx';
#Component({
selector: 'app-textvoice',
templateUrl: './textvoice.page.html',
styleUrls: ['./textvoice.page.scss'],
})
export class TextvoicePage {
text: string;
locale: string;
copyText: string="";
pasteText: string="";
constructor ( private tts: TextToSpeech, public clipboard: Clipboard) {
this.text= '';
this.locale= 'es-MX';
}
playText (){
this.tts.speak({
text: this.text,
locale: this.locale
})
.then((res) => console.log (res))
.catch((err) => console.log (err));
}
stop(){
}
This is my html:
<ion-content>
<ion-button fill="solid" color="light" expand="block" (click)="playText()"><ion-icon name="play-outline"></ion-icon>
A texto
</ion-button>
<ion-button fill="solid" color="light" expand="block" (click)="stop()"><ion-icon name="stop-outline"></ion-icon>
Detener audio
</ion-button>
</ion-content>
You should refer to the documentation for #ionic-native/TextToSpeech as it clearly outlines that stop() is used for this exact purpose.
In your specific scenario, your instance of TextToSpeech is available in the this.tts variable. As such you can invoke stop() by simply calling it on this object within your class's method:
stop(){
this.tts.stop();
}
I already managed to solve, I put this code and when giving it stop if the code worked
stop(){
this.tts.speak("")
}
My simple NextJS page looks like this (results can be viewed at https://www.schandillia.com/):
/* eslint-disable no-unused-vars */
import React, { PureComponent, Fragment } from 'react';
import Head from 'next/head';
import compose from 'recompose/compose';
import Layout from '../components/Layout';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const styles = {
root: {
textAlign: 'center',
paddingTop: 200,
},
p: {
textTransform: 'uppercase',
color: 'red',
},
};
class Index extends PureComponent {
render() {
const { classes } = this.props;
const title = 'Project Proost';
const description = 'This is the description for the homepage';
return (
<Fragment>
<Head>
<title>{ title }</title>
<meta name="description" content={description} key="description" />
</Head>
<Layout>
<p className={classes.p}>amit</p>
<Button variant="contained" color="secondary">
Secondary
</Button>
</Layout>
</Fragment>
);
}
}
export default withStyles(styles)(Index);
I am importing a bunch of components off the #material-ui/core library to style my items. I also have a local style definition assigned to a style constant.
What seems to be happening here is that my style isn't getting rendered on the server which is why the files being served upon load are sans-style. And then the CSS gets rendered by the client-side code. As a result, there's a flash of unstyled content that lasts almost a second, long enough to be noticable.
Any way to fix this? The entire codebase is up for reference at https://github.com/amitschandillia/proost/tree/master/web.
I ran a similar problem when tried to make a production build of my app, that uses material-ui. I manage to solve by adding a JSS Provider like this:
import JssProvider from "react-jss/lib/JssProvider";
class App extends Component {
render() {
<JssProvider>
*the rest of your material-ui components*
</JssProvider>
}
}
Here's the solution - https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js .
Basically, all you need to do is to sync server-side class names with client-side. The link above shows what you need to do to fix that issue.
I have an app with ion-range UI element that is bound to a var using [(ngModel)] (2way) and then i have (ionChange) event that triggers a function that uses the value of ion-range.
Sometimes I need to "set" the range to a specific position by directly changing the var which is bound to ngModel, but I need to avoid triggering ionChange during this operation.
if I do that straightforward (see changeValue method) - the ionChange event will fire the moment the data changes and I need to avoid that (I need to place knob into a new location without triggering the event)
I used a trick with a flag (see changeValueViaFlag method) - now it works as expected, note I also have to use timeout, cause if I don't delay setting flag back to its "normal" state - angular's change detection won't pick up;(
UPDATE:
I tried the trick with ngModelChange which can be found in SO here: ionChange - detect changes only from view to model in Ionic 2 - the problem is with ngModelChange - I am not getting the same "change detection" as I get with ionChange...
So in my app the range is used to select color intensity. If I switch to ngModelChange - shape color intensity is not happening...;/
Question: is there a better way to achieve what I want?
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private testRange: number = 20;
private flag: boolean = true;
constructor(
public navCtrl: NavController,
) {
}
logRange($event) {
if (this.flag) {
console.log("ionChange emitted: ",$event.value, this.testRange)
}
}
changeValue() {
this.testRange = 10;
}
changeValueViaFlag() {
this.flag = false;
this.testRange = 10;
setTimeout(()=>{
this.flag = true;
}, 500)
}
}
<ion-header>
<ion-navbar>
<ion-title>
Ion range test case
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-range [(ngModel)]="testRange" (ionChange)="logRange($event)">
</ion-range>
<button ion-button (click)="changeValue()">Change range value to 10</button>
</ion-content>
click is a DOM event, not related to the higher level ngModel. The proper event for this is ngModelChange. If you want to use DOM events, then forget about ngModel and use $event inside the handler or a #ref.
So, instead of
<input [(ngModel)]="item.completed" (click)="completed(i)" type="checkbox">
it should be
<input [(ngModel)]="item.completed" (ngModelChange)="completed(i)" type="checkbox">
I have to change the color of the navbar of one page when scrolling a bit.
Here we have part of my xml file:
<ion-header no-border>
<ion-navbar color="{{ toolbar_color }}">
<ion-title (click)="change()">{{userdata.Name}}</ion-title>
</ion-navbar>
</ion-header>
<ion-content fullscreen class="container" (ionScrollEnd)="scrollHandler($event)">
I tryed first by changing it using a click event and it worked fine.
change() {
if ( this.toolbar_color == "danger" ) {
this.toolbar_color = "light"
} else {
this.toolbar_color = "danger"
}
}
And this is the ionScrollEnd listener, that does not work. The event is fired correctly, but the changes on toolbar_color are not taking any effect on the navbar.
scrollHandler(event) {
if ( event.scrollTop > 100 ) {
console.log("ScrollEvent --> "+JSON.stringify(event));
this.toolbar_color = "light"
// this.toolbar_change = true;
} else {
this.toolbar_color = "danger"
// this.toolbar_change = false;
}
}
How the hell can I do this?
Thank you :)
Add #ViewChild(Content) content: Content in the TS file and subscribe to scroll end event. refer this link for working version. Also see the ionic forum discussion on this issue
import { Component, ViewChild, ChangeDetectorRef } from '#angular/core';
import { NavController, Content } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild(Content) content: Content;
Arr = Array; //Array type captured in a variable
num:number = 1000;
toolbar_color: string;
constructor(public navCtrl: NavController, public ref : ChangeDetectorRef) {
this.toolbar_color="secondary";
}
changeColor(){
this.toolbar_color="primary";
this.ref.detectChanges();
}
ionViewDidLoad() {
//this.content.enableJsScroll();
this.content.ionScrollEnd.subscribe(() => {
this.changeColor();
});
}
}
HTML file
<ion-header>
<ion-navbar [color]="toolbar_color">
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Welcome to Ionic!</h2>
<p>
This starter project comes with simple tabs-based layout for apps
that are going to primarily use a Tabbed UI.
</p>
<p>
Take a look at the <code>pages/</code> directory to add or change tabs,
update any existing page or create new pages.
</p>
<div *ngFor="let i of Arr(num).fill(1)">{{i}}</div>
</ion-content>
Update-1
Added code to change color on scrolling
Sometimes angular will not run changeDetector automatically. we can manually trigger it by using ChangeDetectorRef. it's added to detect the changes while scrolling.
Working version is also updated. Please check the above link
I'm trying to make a dynamic Sidebar on my website, but the menu button is in another component (Navbar). How can I get them to communicate with each other through vuex? Look, I know how to do it in the same component, but I'm struggling here to pass this boolean state from Navbar to Sidebar.
Define your store as follows:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
sideBarOpen: false
},
getters: {
g_sideBarOpen(state){
return state.sideBarOpen
}
},
mutations: {
toggleSideBar(state){
state.sideBarOpen = !state.sideBarOpen;
}
},
});
In NavBar component click listener for menu button
<template>
<button #click="toggleSideBar" class=myMenuBtn"></button>
</template>
<script>
export default{
methods:{
toggleSideBar(){
this.$store.commit('toggleSideBar');
}
}
}
</script>
now in the main component where you host the SideBar component
<template>
<side-bar v-show="showSideBar"></side-bar>
</template>
<script>
import SideBar from './SideBar'
export default{
components:{
'side-bar': SideBar
},
computed:{
showSideBar(){
this.$store.getters.g_sideBarOpen;
}
}
}
</script>
The whole purpose of using Vuex is to have a common state across your components. You don't have to communicate this from one component, they share the state.
If you commit a mutation in one component, to set a variable : state.myVar, you can access the modified this.$store.state.myVar in the other component, which will always reflect the modified value.
Please add your code samples if it is not working like this.