Ionic version: (check one with "x")
[ ] 1.x
[x] 2.x
I'm submitting a ... (check one with "x")
[ ] bug report
[x] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
Current behavior:
When multiple slides are changed (substituted with other data) with loop enabled duplicated slides are not updated even on Slides.prototype.update method call. So loop ends up to be broken.
Expected behavior:
Duplicated slides should update on Slides.prototype.update method call if loop is enabled or destroyLoop(s) and createLoop(s) method should be public and available on Slides instance to fix the loop after update.
Steps to reproduce:
1) Create slides sourced from array and projected to template with *ngIf and loop enabled
2) Update an array
3) Swipe slides
Related code:
component.js
imports...
@Component(...)
export class Component {
visibleItems = [{...}, {...}, {...}, {...}]
loop = true
...
updateSlider() {
this.visibleItems[lastOrFirstSlide] = newFirstOrLastSlide
}
...
}
template.html
<ion-slides #slider [loop]="loop" (ionSlideNextEnd)="updateSlider()" (ionSlidePrevEnd)="updateSlider()">
<ion-slide *ngFor="let item of visibleItems">
{{ item.prop }}
</ion-slide>
</ion-slides>
So the possible solution might be to add destroyLoop(s) and createLoop(s) to common update method:
export function update(s: Slides, plt: Platform, updateTranslate?: boolean) {
...
if (s._init && s._isLoop) {
destroyLoop(s)
createLoop(s)
}
...
}
or make functions above member props of Slides instance so it could be fixed like this:
imports...
@Component(...)
export class Component {
visibleItems = [{...}, {...}, {...}, {...}]
loop = true
...
updateSlider() {
this.visibleItems[lastOrFirstSlide] = newFirstOrLastSlide
this.slides.destroyLoop()
this.slides.createLoop()
}
...
}
Other information:
Ionic info: (run ionic info from a terminal/cmd prompt and paste output below):
Cordova CLI: 6.5.0
Ionic Framework Version: 2.2.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
ios-deploy version: 1.9.0
ios-sim version: 5.0.8
OS: macOS Sierra
Node Version: v6.9.5
Xcode version: Xcode 8.2.1 Build version 8C1002
Hello, thanks for opening an issue with us. We will look into this issue.
@jgw96 any chance to push up the priority of this?
Hello all! I am going to close this issue as a duplicate of https://github.com/driftyco/ionic/issues/6515
This is not a duplicate of driftyco#6515 . We have a serious problem when loop is set to true. Two ion-slide will be added called duplicate.
I have spent some time searching for a solution to this issue without luck. Debuging I have discovered what is the method that refresh the content when touch event is fired and this is fixLoop(s, plt). Hope that this help to find a final solution to this issue. Regards
Hi!
When you're going from the last slide to the first one, use this.slider.slideTo(1);.
When you're going from the first slide to the last one, use this.slider.slideTo(X);
You can know which direction you're taking by using getActiveIndex() and getPreviousIndex().
X being the value of your last index.
Here is a working example :
<ion-slides #slider (ionSlideWillChange)="onChangeMonth()" >
...
</ion-slides>
import {Slides} from 'ionic-angular';
export class MyClass {
@ViewChild('slider') slider: Slides;
private onChangeMonth() {
this.doMyStuff().then((indexes) => {
// Last slide to first slide
if (indexes[0] == X + 1 && indexes[1] == X) { // Change X and X + 1
this.slider.slideTo(1);
}
// First slide to last slide
if (indexes[0] == 0 && indexes[1] == 1){
this.slider.slideTo(X); // Change X to the last index of your slider
}
})
}
private doMyStuff() {
return new Promise ((resolve, reject) => {
// Here is where you update your values each time your slide change.
...
return ([this.slider.getActiveIndex(), this.slider.getPreviousIndex()])
})
}
}
Enjoy.
PS : Thank you @AdhemarBouchet. I found out how to make it working because you found the fixLoop function that I did inspect, good job! ;-)
In html set autoplay=
Use event (ionSlideDidChange) to make slides autoplay again.
If you do not deal with ionSlideDidChange, the slides will stop autoplay when coming back to the first slide.
HTML:
In typescript:
@ViewChild('slides_banner') slides_banner;
changeSlides(event) {
this.slides_banner.startAutoplay();
}
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.
Following solution works for me
html
<ion-slides (swipe)="swipeHandler($event)">
<ion-slides *ngFor="let item of items">{{item}}</ion-slides>
</ion-slides>
````javascript
@ViewChild(Slides)
public slides:Slides;
public swipeHandler(event) {
//to jump to last slide
if(this.slides.isBegginning()){
if(event.direction == 4){
this.slides.slideTo(this.items.length - 1)
}
}
//to jump to first slide
if(this.slides.isEnd()){
if(event.direction == 2){
this.slides.slideTo(0)
}
}
}
@HostListener('window:keyup', ['$event'])
public onKeyUp(ev: KeyboardEvent) {
if(ev.key === "ArrowLeft") {
if(this.slides.isBeginning()){
this.slides.slideTo(this.items.length - 1);
}
}
if(ev.key === "ArrowRight") {
if(this.slides.isEnd()){
this.slides.slideTo(0);
}
}
}
````
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Most helpful comment
This is not a duplicate of driftyco#6515 . We have a serious problem when loop is set to true. Two ion-slide will be added called duplicate.