Ionic2更改搜索问题,首先忽略了变化



我使用ionic2开发了一个测验应用。这些问题是从数据库中提取的,并使用<ion-slides> -Component显示。模板的重要部分看起来如下:

<ion-content padding>
  ...
  <ion-slides *ngIf="status === QuizState.running" pager="true" paginationType="progress">
    <ion-slide *ngFor="let question of questions; let index = index">
      <span>{{ question|json}}</span>
      ...
    </ion-slide>
  </ion-slides>
  ...
</ion-content>

组件代码看起来如下:

import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core';
import { NavController, Slides } from 'ionic-angular';
import { QuizLoaderService, QuizType, QuizDefinition } from '../../components/quiz-item/quiz-loader.service';
import { SamplePipe } from 'ngx-pipes/src/app/pipes/array/sample';
import { ShufflePipe } from 'ngx-pipes/src/app/pipes/array/shuffle';
import { Observable } from 'rxjs';
import 'rxjs/add/observable/from';
import 'rxjs/add/observable/forkJoin';
enum QuizState {
    idle,
    running,
    finished
}
@Component({
    selector: 'page-quiz',
    templateUrl: 'quiz.html',
    providers: [
        SamplePipe, ShufflePipe, QuizLoaderService
    ],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class QuizPage {
    private slides: Slides;
    private status: QuizState = QuizState.idle;
    private questions: Array<QuizType|QuizDefinition> = [];
    private readonly numberOfQuestions = 10;
    // make enum accessable from the view
    readonly QuizState = QuizState;
    constructor(public navCtrl: NavController, private quizLoaderService: QuizLoaderService) {}
    @ViewChild(Slides) set slidesViewChild(slides: Slides) {
        if(slides) {
            slides.onlyExternal = true;
            slides.ionSlideWillChange.subscribe(slides => {
                // load the after next question in advance
                if(!slides.isEnd()) {
                    let index: number = slides.getActiveIndex() + 1;
                    let quizType: QuizType = <QuizType>this.questions[index];
                    this.quizLoaderService.loadQuizItem(quizType).subscribe((item: QuizDefinition) => this.questions[index] = item);
                }
            });
        }
        this.slides = slides;
    }
    startQuiz() {
        this.status = QuizState.running;
        // generate an array of question types
        this.questions = this.quizLoaderService.getQuizItems(this.numberOfQuestions);
        // fetch data for the first two questions
        let startingQuestions: Observable<QuizDefinition>[] = [0, 1].map(index => {
            let quizType = <QuizType>this.questions[index];
            return this.quizLoaderService.loadQuizItem(quizType);
        });
        Observable.forkJoin(startingQuestions).subscribe(
          // update first two items with actual question data
          (items: QuizDefinition[]) => this.questions.splice(0, items.length, ...items)
        );
    }
    ...
}

首先,questions数组仅被QuizTypes填充,因此可以创建幻灯片。然后,我为数据库中的前两个问题加载问题数据(QuizDefinition(。在进入下一个问题时,我在此之后为问题加载数据。

在我的PC上可以按预期工作,但是在移动设备上,当视图渲染或更改只是无法识别时,第一个问题不会更新。以任何方式,JSONPipe仍然显示问题类型QuizType而不是问题数据。第一个幻灯片在第一个幻灯片正常工作后。

编辑

在我的PC上,我为数据库使用模型。没有延迟。我添加了一个随机延迟,现在的行为与移动设备相同。第一个问题数据未设置。

我现在解决了它,通过切换到完全手动控制变更检测,并且只有在预期发生更改时才能运行它。

import { Component, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { NavController, Slides } from 'ionic-angular';
import { QuizLoaderService, QuizType, QuizDefinition } from '../../components/quiz-item/quiz-loader.service';
import { SamplePipe } from 'ngx-pipes/src/app/pipes/array/sample';
import { ShufflePipe } from 'ngx-pipes/src/app/pipes/array/shuffle';
import { Observable } from 'rxjs';
import 'rxjs/add/observable/forkJoin';
enum QuizState {
    idle,
    running,
    finished
}
@Component({
    selector: 'page-quiz',
    templateUrl: 'quiz.html',
    providers: [
        SamplePipe, ShufflePipe, QuizLoaderService
    ],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class QuizPage {
    private slides: Slides;
    private status: QuizState = QuizState.idle;
    private questions: Array<QuizType|QuizDefinition> = [];
    private readonly numberOfQuestions = 10;
    // make enum accessable from the view
    readonly QuizState = QuizState;
    constructor(public navCtrl: NavController, private quizLoaderService: QuizLoaderService, private changeDetectorRef: ChangeDetectorRef) {}
    ngAfterViewInit() {
        // disable change detection
        this.changeDetectorRef.detach();
    }
    ...
    startQuiz() {
        this.status = QuizState.running;
        this.questions = this.quizLoaderService.getQuizItems(this.numberOfQuestions);
        //this.changeDetectorRef.detectChanges();
        // fetch data for the first two questions
        let startingQuestions: Observable<QuizDefinition>[] = [0, 1].map(index => {
            let quizType = <QuizType>this.questions[index];
            return this.quizLoaderService.loadQuizItem(quizType);
        });
        Observable.forkJoin(startingQuestions).subscribe((items: QuizDefinition[]) => {
            this.questions.splice(0, items.length, ...items);
            // run change detection when changes happen
            this.changeDetectorRef.detectChanges();
        });
    }
    ...
}

相关内容

  • 没有找到相关文章

最新更新