3

Hi I'm using ngFor to create an set of 3 slides while starting in the middle so I'm guaranteed to be able to slide to left or right on start.

When I slide right I can simple listen to the reachedEnd and push another slide to the array i'm looping.

but I have a problem with adding a slide to the beginning. If I do the same as above and use e.g. array.unshift() or spread to add an item to the beginning, the view think it's on position 0 and snaps the view to the new slide.

The code below would work but it animates the slide change back to index 1.

slide = [0,1,2] //example to loop
slideChanged(event) {
    if(this.slides.isBeginning()){
        this.slide = [this.slide[0]-1, ...this.slide];
        this.slides.update();
        this.slides.slideTo(1)
    }
}

<ion-slides [initialSlide]="1" (ionSlideDidChange)="slideChanged($event)">
    <ion-slide *ngFor="let item of slide">
        <h1>Slide {{item}}</h1>
    </ion-slide>
</ion-slides>

Any help is appreciated!

2 Answers 2

13

You can do that by using the ionSlideNextEnd and ionSlidePrevEnd events from the Slides. Please take a look at this working plunker

The view

<ion-header>
  <ion-navbar>
    <ion-title>Dynamic slides Demo</ion-title>
  </ion-navbar>
</ion-header>
<ion-content>
    <ion-slides #slider (ionSlideNextEnd)="loadNext()" (ionSlidePrevEnd)="loadPrev()" [initialSlide]="1">
        <ion-slide *ngFor="let n of numbers">
            <h2>Current slide: {{n}}</h2>
        </ion-slide>
    </ion-slides>
</ion-content>

The component

@Component({...})
export class HomePage {
    @ViewChild('slider') private slider: Slides;

    numbers = [0,1,2];
    firstLoad = true;

    constructor() {}

    loadPrev() {
        console.log('Prev');
        let newIndex = this.slider.getActiveIndex();

        newIndex++;
        this.numbers.unshift(this.numbers[0] - 1);
        this.numbers.pop();

        // Workaround to make it work: breaks the animation
        this.slider.slideTo(newIndex, 0, false);

        console.log(`New status: ${this.numbers}`);
    }

    loadNext() {
        if(this.firstLoad) {
          // Since the initial slide is 1, prevent the first 
          // movement to modify the slides
          this.firstLoad = false;
          return;
        }

        console.log('Next');
        let newIndex = this.slider.getActiveIndex();

        newIndex--;
        this.numbers.push(this.numbers[this.numbers.length - 1] + 1);
        this.numbers.shift();

        // Workaround to make it work: breaks the animation
        this.slider.slideTo(newIndex, 0, false);

        console.log(`New status: ${this.numbers}`);
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

thanks! I also figured out the only workaround was setting slide speed to 0, i guess that'll work for now
Glad to hear that it helped :)
If you add "loop" to <ion-slides #slider loop (ionSlideNextEnd)="loadNext()" (ionSlidePrevEnd)="loadPrev()" [initialSlide]="1"> it's going to have that pretty slide transition. Currently it has kinda bounce and it just takes to to another slide
For me I had to do await this.slider.getActiveIndex(); to get the index
2

For you who wonder why this not works on Ionic 4, just add little bit changes on typescript component

This code below works on IONIC 4 :

ionSlideNextEnd(){
  if(this.firstLoad) {
    // Since the initial slide is 1, prevent the first 
    // movement to modify the slides
    this.firstLoad = false;
    return;
  }

  console.log('Next');
  this.daySlider.getActiveIndex().then(idx=>{
      let newIndex=idx
      console.log(newIndex)
      newIndex--;
      this.numbers.push(this.numbers[this.numbers.length - 1] + 1);
      this.numbers.shift();

      // Workaround to make it work: breaks the animation
      this.daySlider.slideTo(newIndex, 0, false);

      console.log(`New status: ${this.numbers}`);
  });


}

ionSlidePrevEnd(){
console.log('Prev');
this.daySlider.getActiveIndex().then(idx=>{
    let newIndex=idx
    console.log(newIndex)
    newIndex++;
    this.numbers.unshift(this.numbers[0] - 1);
    this.numbers.pop();

    // Workaround to make it work: breaks the animation
    this.daySlider.slideTo(newIndex, 0, false);

    console.log(`New status: ${this.numbers}`);
});
}

Or Much more simpler you can remove getter for Active Index, use below code for Ionic 4:

ionSlideNextEnd(){
    if(this.firstLoad) {
        this.firstLoad = false;
        return;
    }else{
        this.numbers.push(this.numbers[this.numbers.length - 1] + 1);
        this.numbers.shift();

        // Workaround to make it work: breaks the animation
        this.daySlider.slideTo(1,0,false);
        this.monthViewData.selectedTime=new Date(this.monthViewData.selectedTime.setDate(this.monthViewData.selectedTime.getDate()+1));
        this.eventSource = this.tmp_events.filter((item)=>{
            if(item.startTime >= this.monthViewData.selectedTime.setHours(0,0,0,0) && item.endTime < this.monthViewData.selectedTime.getTime()){
                return item;
            }
        });
    }

}

ionSlidePrevEnd(){

    this.numbers.unshift(this.numbers[0] - 1);
    this.numbers.pop();

    this.daySlider.slideTo(1,0,false);
    this.monthViewData.selectedTime=new Date(this.monthViewData.selectedTime.setDate(this.monthViewData.selectedTime.getDate()-1));
    this.eventSource = this.tmp_events.filter((item)=>{
        if(item.startTime >= this.monthViewData.selectedTime.setHours(0,0,0,0) && item.endTime <= this.monthViewData.selectedTime.getTime()){
            return item;
        }
    });
}

1 Comment

This code has a bunch of monthViewData stuff that doesn't make any sense

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.