Выражение изменилось после его проверки - Обновления подписки на событие - PullRequest
0 голосов
/ 01 апреля 2020

Хотя я знаю причину, по которой это ERROR происходит, тем не менее, я хотел бы знать, как преодолеть в следующем сценарии:

У меня есть универсальный загрузчик c в app.component , Для некоторых дочерних маршрутов будет обновляться значение загрузчика в ngOnInit жизненном цикле, пока не будут получены записи. Кроме того, я не хочу использовать resolver, так как я анализирую параметры запроса в компоненте, а затем перехожу к службе для извлечения записей.

Значение ERROR связано со значением по умолчанию: загрузчик на false и меняется на true в течение жизненного цикла дочернего компонента ngOnInit hook.

Пожалуйста, посмотрите следующий фрагмент:

// app.component.ts
 viewModel = {
    showLoader: false
};
ngOnInit() {
    this.eventService.on(ApplicationEvents.SHOW_FULL_PAGE_LOADER, (value) => {
        this.viewModel.showLoader = value;
    });
}
// app.component.html
<div class="full-page-loader" *ngIf="viewModel.showLoader"><em class="fa fa-cog fa-spin loader-icon"></em></div>

И следующее фрагмент из lazyloaded дочернего компонента:

ngOnInit() {
    this.loadData();
    this.cart = this.cartService.getCart();
  }

private loadData() {
this.eventService.showFullPageLoader(); // <-- This will emit an event to show the loader 
this.umrahDataService.getServices(UmrahServiceType.Visa).then((resp) => {
  this.visas = resp.map((v) => {
    v.image = '/assets/img/umrah/visa-processing.jpg';
    return v;
  });

  this.eventService.hideFullPageLoader();
  this.actionInProcess = false;
}).catch((er) => {
  this.alertService.alert('SERVER_ERROR');
  this.eventService.hideFullPageLoader();
  this.actionInProcess = false;
});
}

Ошибка: ExpressionChangedAfterItHasBeenCheckedError: Выражение изменилось после его проверки. Предыдущее значение: 'ngIf: false'. Текущее значение: 'ngIf: true'. at viewDebugError (core. js: 19629) в expressionChangedAfterItHasBeenCheckedError (core. js: 19617) в checkBindingNoChanges (core. js: 19833) в checkNoChangesNodeInline (core. js: 29Nhange check) 1033 *: 29522) в debugCheckNoChangesNode (core. js: 30126) в debugCheckDirectivesFn (core. js: 30054) в Object.eval [как updateDirectives] (AppComponent. html: 3) в Object.debugUpdates. updateDirectives] (core. js: 30043) в checkNoChangesView (core. js: 29421)

Хотя я тоже пробовал BehaviorSubject с async pipe, и это не помогло или. Ждем отзывов. Спасибо

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Всякий раз, когда вы изменяете данные после загрузки представления, позвольте Angular watcher, чтобы переварить изменения. Angular имеет службу ChangeDetectorRef. Вы можете добавить эту услугу и заставить angular обнаружить и включить изменения в цикл дайджеста.

import { Component, ChangeDetectorRef  } from '@angular/core';

@Component({
  selector: 'app-your-comp',
  templateUrl: 'your-comp.component.html',
  styleUrls: ['your-comp.component.scss']
})
export class YourCompPage {
    constructor(private changeDetectorRef: ChangeDetectorRef) {}

    ngAfterViewInit() {
        ..any data changes or your flag in this case..
        this.changeDetectorRef.detectChanges();
        // -- OR --
        this.eventSubscription.someEvent(() => {
            ..any data changes or your flag in this case..
            this.changeDetectorRef.detectChanges();
        });
    }
}

PS https://indepth.dev/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error/

0 голосов
/ 01 апреля 2020

В большинстве случаев перемещение вашего реактивного кода на ngAfterViewInit помогает. Так что в вашем дочернем компоненте вместо:

ngOnInit() {
    this.loadData();
    this.cart = this.cartService.getCart();
}

используйте

ngAfterViewInit() {
    this.loadData();
    this.cart = this.cartService.getCart();
}

Вы также можете использовать setTimeout в своем app.component.ts, но это больше похоже на взлом, а не на решение.

...