Ionic 2 do not show slides when exercise is done

2019-08-20 00:14发布

Here I have the outcome of the JSONOBJ:enter image description here

I have ion-card in my home.html with the method navigate() which looks like this:

    navigate(event, exercise, exercise2, exercise3, exercise4){    
      this.navCtrl.push(exerciseSlides, {
                clickedExercise: exercise,
                secondExercise: exercise2,
                thirdExercise: exercise3,
                fourthExercise: exercise4
      });
  }

and these are 2 of the cards:

 <ion-card *ngIf="oefening1" (click)="navigate($event, oefening1, oefening2, oefening3, oefening4)" class="{{ oefening1 }}" margin-vertical>
    <img src="assets/img/{{ oefening1 }}.jpg"/>
    <div *ngIf="exercise1IsDone || allExercisesDone" (click)="$event.stopPropagation()" class="overlay">
      <ion-icon name="checkmark-circle" class="checkmark"></ion-icon>
    </div>

    <ion-card-content>
      <ion-card-title>{{ oefening1 }}</ion-card-title>
      <p>Setjes: {{ set1 }}</p>
      <p>Herhalingen: {{ rep1 }}</p>
    </ion-card-content>
  </ion-card>

  <ion-card *ngIf="oefening2" (click)="navigate($event, oefening2, oefening1, oefening3, oefening4)" class="{{ oefening2 }}" margin-vertical>
    <img src="assets/img/{{ oefening2 }}.jpg"/>    
    <div *ngIf="exercise2IsDone || allExercisesDone" (click)="$event.stopPropagation()" class="overlay">
      <ion-icon name="checkmark-circle" class="checkmark"></ion-icon>
    </div>
    <ion-card-content>
      <ion-card-title>{{ oefening2 }}</ion-card-title>
      <p>Setjes: {{ set2 }}</p>
      <p>Herhalingen: {{ rep2 }}</p>
    </ion-card-content>
  </ion-card>

I have an exerciseSlides.html like this:

<ion-content>
  <ion-slides #exercisesSlider>
        <ion-slide *ngFor="let ex of allExercises; let i = index" id="{{ ex.exercise }}">
            <ion-grid>
                <ion-row>
                    <ion-col col-12>
                        <div (click)="playVid(ex.exercise)" padding-bottom>
                            <img [src]="ex.path" />
                        </div>
                        <div text-center>
                            <!-- can't go back if it's the first exercise -->
                            <button *ngIf="i > 0" ion-button round (click)="previousExercise()">Vorige</button>
                            <!--<button ion-button block [disabled]="!disabledBtn">Block Button</button>-->
                            <!-- will not have a next exercise if it's the last one -->
                            <button *ngIf="i < 4" ion-button round (click)="nextExercise(i, ex.exercise, ex.done)">Voltooi</button>

                            {{ ex.done }}
                        </div>
                    </ion-col>
                </ion-row>
            </ion-grid>
        </ion-slide>
    </ion-slides>
</ion-content>

And an exerciseSlides.ts like this:

export class exerciseSlides {
  @ViewChild('exercisesSlider') slides: Slides;
  public fullPath: string;
  public disabledBtn: boolean;
  public allExercises: any[] = []; // INITIALIZE A VAR THAT'LL HOLD ALL EXERCISES
  public date: any = moment().format('L');

   constructor( public navCtrl: NavController, private streamingMedia: StreamingMedia, public params: NavParams, public modalCtrl: ModalController) {
        // GET ALL EXERCISES AND THE IMAGE PATH ON PAGE CONSTRUCRION
        this.allExercises.push({
            exercise: params.get("clickedExercise"),
            path: 'assets/img/' + params.get("clickedExercise") + '.jpg',
            done: false
        });
        this.allExercises.push({
            exercise: params.get("secondExercise"),
            path: 'assets/img/' + params.get("secondExercise") + '.jpg',
            done: false
        });
        this.allExercises.push({
            exercise: params.get("thirdExercise"),
            path: 'assets/img/' + params.get("thirdExercise") + '.jpg',
            done: null
        });
        this.allExercises.push({
            exercise: params.get("fourthExercise"),
            path: 'assets/img/' + params.get("fourthExercise") + '.jpg',
            done: null 
        });     

        this.disabledBtn = false;
    }

    ionViewDidEnter() {
        // block the swipe to change page
        this.slides.lockSwipes(true);     
    }

    nextExercise(i, id, done) {
        this.slides.lockSwipes(false);
        this.slides.slideNext();
        this.slides.lockSwipes(true);

        //Here is set the done value of opened slide to true, but gets overrided by the constructor.
        this.allExercises[i].done = true;

        console.log(this.allExercises[i].done);

        if (this.allExercises[i].exercise == 'lagerugklacht'){
            console.log('check', this.allExercises[i]);
            localForage.setItem('exercise1IsDone', [this.allExercises[i].exercise, this.allExercises[i].done]);    
            console.log('localForageItem: ', localForage.getItem("exercise1IsDone"));
        }

        let modal = this.modalCtrl.create(ModalPage);
        modal.present();

        if(i == 3){
            console.log("lastOne");
            this.navCtrl.push(HomePage);
            localForage.setItem('didAllExercises', [true, this.date]);
        }
    }
}

How do I set the value of this.allExercises[i].done to true and create an *ngIf to check if exercise is done, and when its done than do not show slide anymore?

The allExercises.done will always enters first to false because I set that in the constructor it changes after I emit the nextExercise() but how can I change the poperty of allExercises.done to true in the array and stays true? So if its done it has to skip that slide and move on to the next one which is not done.

1条回答
SAY GOODBYE
2楼-- · 2019-08-20 00:40

So here's what you can do:

You'll need to update your database so every exercise have a done field.

I don't know how much exercises do you have, but select only 4 where done: false.

It's really good to have offline data that your user can see at anytime, but since this is a app that fetchs videos i think there's no need for keeping a localForage/localStorage for this, only if you have a page where the user can see what exercises he has done.

Don't save arrays, it's bad, it's ugly, it's not so good for you to manipulate. Use objects

So on your nextExercise you can do this

nextExercise(i, id, done) {
  // SAVE YOUR EXERCISE FOR THIS USER ON YOUR DATABASE, YOU HAVE THE EXERCISE ID
  // IT'S SO MUCH EASIER FOR YOU TO KEEP TRACK.
  // AND IF THE USER DELETES THE APP AND INSTALL AGAIN, YOU CAN DOWNLOAD HIS PROGRESS
  saveYourExerciseMethod().then(() =>{
    this.slides.lockSwipes(false);
    this.slides.slideNext();
    this.slides.lockSwipes(true);

    // I DON'T KNOW HOW LOCALFORAGE WORKS, BUT IF YOU HAVE A STATIC 'exercise1IsDone'
    // THEM IT'LL ALWAYS OVERRIDE THAT EXERCISE, YOU'LL NEVER COMPLETE ANOTHER
    // EXERCISE
    // YOU'LL NEED TO SAVE AN OBJECT WITH ALL YOUR EXERCISES COMPLETED OR
    // SET THE NAME DINAMICALLY
     localForage.setItem(this.allExercises[i].exercise, { exercise: this.allExercises[i].exercise, done: true]);

    // DON'T KNOW WHAT THIS DO, SO I1LL NOT CHANGE IT
    let modal = this.modalCtrl.create(ModalPage);
    modal.present();

    if(i == 3){
        this.navCtrl.push(HomePage);
        localForage.setItem('didAllExercises', {completed: true, date: this.date});
    }
  });
}

So as far as i understod your code and application, this is what i can adivise you. Can't post more code because this is what i can do for what i've seen.

Hope this helps you

查看更多
登录 后发表回答