Type: bug
Ionic Version: 2.x
Platform: all
Hey Ionic 2 team,
Ionic 2 ion-slides
component seems to be working properly when ion-slide
are either hardcoded into the template or when they are created with a ngFor iterating over an array that is not empty/not modified.
If the ngFor is first iterating over an empty array and then the array is modified, the slides seems to be broken (in particular, looping is not working properly).
This bug can maybe be generalised to any ion-slide
s that are dynamically added/removed after the first creation of the ion-slides
but I have not tested this.
To reproduce the bug, clone, install and launch the sample app of this repo: https://github.com/4ian/ionic2-slides-test
Click on the button to fill the array used to generate the slides. The second slider won't work properly. The first slider will be working but I've used a workaround: the slider is not created when the array is empty.
Thank you for the workaround - helped a ton
What was the workaround here?
In my case, I delayed the creation of the slider until I have all the data needed (a simple *ngIf="items.length"
to ensure that the items array was filled with fetched data).
See: https://github.com/4ian/ionic2-slides-test/blob/master/app/pages/hello-ionic/hello-ionic.html
I found I was also having problems on update, so I am briefly (10ms) setting the binding source to empty whenever it changes, so the ngIf deletes and recreates the slides rather than updating them incorrectly.
Thank's
Really workarounds !!
Thanks.
I had to replace <ion-slide-box>
with <ion-slides>
to get it working.
On the swipper api you can see what you could put in the slide options.
http://idangero.us/swiper/api/#.WIandPHhCkA
eg ###(onReachEnd):
mySlideOptions = {
pager:true,
paginationClickable: true,
onReachEnd : function(){
console.log("end");
this.showButton = true;
}
};
in the view you put the options:
<ion-slides [options]="mySlideOptions">
Voila
@t1gu1 It seems ionic guys are rewriting slides component.
how to made slide dinamic from database with ionic 2 ?
Two thing is really important when you are using ionic, and develop for mobile.
1, Try out your stuff without inspector window also on Chrome.
2, Instead of canvas use svg, as it's horrible performance wise. Now my virtual scrolling started to work smoothly - there are lot's of component which are not enough flexible, or just making me sad. (ng-lazyload-image) - it's a very heavy stuff, ionic one is not working. simply use ... 4-5 times faster.
P.s.:
ion-slide is making a mysterious 2 additional slides on the fly, which is very sensitive when the data is dynamic.
+1
=> Can't bind to 'options' since it isn't a known property of 'ion-slides'
loop breaks after ion-slices dynamic update.
template:
<ion-slides pager [autoplay]="2000" [loop]="true" #slides>
<ion-slide *ngFor="#item of items">
{{ item}}
</ion-slide>
</ion-slides>
component:
items=[ 1, 2, 3]; // works fine so far
@ViewChild('slides') slides: Slides;
constructor(private http: Http) {
}
ionViewDidLoad() {
this.http.get('...').then(r=>{
this.items=r; // e.g. [4, 5, 6]
setTimeout(()=>{ // delay to update
this.slides.update(); // loop broken here.
}, 500);
});
}
By the way, it works fine with ionic 1.
did you manage to fix this issue? I'm facing similar issue when I try to specify an initial slide having [hidden]
active.
SlideTo
also doesn't work
I made the same kinda workaround, something like what has been already posted here.
*ngIf="!isUpdatingSlides"
on ion-slides
element,isUpdatingSlides: boolean = false;
setTimeout(() => {
this.updatingSlides = true;
setTimeout(() => {
this.updatingSlides = false;
}, 10);
}, 10);
The time outs here make sure that element has been done changing and slides already updated so we don't get any more issues (I've encounter some).
This will recreate the element but however on every update you will encounter a disappearance for more than 50ms and even some funny temporary behaviors but the good thing is that it works and it gives the feelings of something changed!! It's good when you're gonna put some dummy contents or pre-cached contents before getting actual values from server and changing it or change it with every update user might want to see.
I solve it with dirty way for the dynamic slides autoplay.
Ionic autoplay options for dynamic slides get the error
so I import the following library and solve it.
import { Observable } from "rxjs/Rx";
Add the following line,
in the
constructor(){
**Observable.interval(5000).subscribe(() => {
if(this.slides.isEnd())
this.slides.slideTo(0,1000);
else
this.slides.slideNext(1000);
});**
}
+1
+1
+1
I have a component inside of a slider tag inside of a page with an *ngFor which does work the first time i route to the page with setRoot(). The 2. time it does not work so now i have to spend a lot of time to write my own hack on top of ionic.
similar: https://stackoverflow.com/questions/38552261/ionic2-slider-is-not-working-with-ngfor-angular2
After a lot of painful research I found solution. In my case I use several slides with list of items (custom component) on each of them with infinite scroll. Here is info, that can be helpful for other developers:
ngFor list
, that located inside slide you can add pipe that takes listChanged
string argument and always return list public transform(items: Array<any>, listChanged: string): Array<any> {
return items;
}
And in your component define public listChanged: string;
and change it to new value every time when list updated
this.listChanged = Math.random().toString(16).slice(2);
Note, that when you add some items in list, slide height will not change automatically and you need to change it manually. This comment can be helpful. In my case I call "slideDidChange(); slideWillChange();"
on each infinite scroll calback
Unfortunately infinite scroll will not disappear manually inside slides. But you can hide it at all by css and it will still work
<ion-infinite-scroll class="component-infinite-scroll" ...
.component-infinite-scroll {
height: 0;
overflow: hidden;
}
Note: beware of side effects. I can't guarantee that this hack will work in all possible cases. I'm not sure that this can be used in production.
In my case, a simple solution did the trick.
My ion-slides Setup:
<ion-slides #slides *ngIf="specialEventItems && specialEventItems.length" loop dir="ltr" pager autoplay="3000" speed="600" effect="slide">
<ion-slide *ngFor="let splEvent of specialEventItems" tappable (tap)="showEvent(splEvent.id)">
<img [src]="splEvent.banner">
</ion-slide>
</ion-slides>
As you can see, I have a ngFor to load slides from httpAPI. Also my ion-slides loops & autoplays with slide effect.
I had an implementation of 'Pull to Refresh' to reload Slides from httpAPI; the above code worked without issues until the data is reloaded. Few duplicate ion-slide elements were the culprit, causing bad looping.
Solution for me:
getSpecialEvents () {
this.specialEventItems = []; // <===== THIS DID THE TRICK!!
this.api.get('special-events').subscribe(
(res) => {
this.specialEventItems = res['events'];
}
);
}
Simply, I rest the slides variable to empty array before fetching new data from httpAPI.
I guess, the duplicated elements gets deleted once I reset the slides to an empty array.
Hope this helps someone.
Thanks for the issue! We have moved the source code and issues for Ionic 3 into a separate repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.
Thank you for using Ionic!
Thanks for the issue! We have moved the source code and issues for Ionic 3 into a separate repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.
Thank you for using Ionic!
Issue moved to: https://github.com/ionic-team/ionic-v3/issues/89
Most helpful comment
+1