1

虽然我知道发生这种情况的原因ERROR,但是,我想知道如何在以下情况下克服:

我有一个通用加载器app.component。对于某些子路由,它会在ngOnInit生命周期中更新加载器值,直到获取记录。另外,我不想使用resolver,因为我正在解析组件中的查询参数,然后传递给服务以获取记录。

ERROR是由于在子组件生命周期钩子期间加载器的默认值false和更改。truengOnInit

请查看以下代码段:

// 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>

以下是延迟加载子组件的片段:

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;
});
}

ERROR 错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'ngIf: false'。当前值:'ngIf: true'。在 viewDebugError (core.js:19629) 在 expressionChangedAfterItHasBeenCheckedError (core.js:19617) 在 checkBindingNoChanges (core.js:19833) 在 checkNoChangesNodeInline (core.js:29533) 在 checkNoChangesNode (core.js:29522) 在 debugCheckNoChangesNode (core. js:30126) 在 debugCheckDirectivesFn (core.js:30054) 在 Object.eval [as updateDirectives] (AppComponent.html:3) 在 Object.debugUpdateDirectives [as updateDirectives] (core.js:30043) 在 checkNoChangesView (core.js: 29421)

尽管我也尝试过BehaviorSubject使用async管道,但这也无济于事。期待反馈。谢谢

4

3 回答 3

1

在大多数情况下,将您的反应式代码移动到ngAfterViewInit帮助。所以在你的子组件中,而不是:

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

利用

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

你也可以setTimeout在你的中使用app.component.ts,但这更像是一个 hack 而不是一个解决方案。

于 2020-04-01T10:31:39.393 回答
1

每当您在视图加载后更改数据时,让 Angular 观察者消化更改。Angular 有 ChangeDetectorRef 服务。您可以注入此服务并强制角度检测并包含摘要周期中的更改。

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/

于 2020-04-01T10:42:13.387 回答
0

Angular 变更检测过程是同步的,为了避免这个错误,我们可以将其作为异步过程,并且我们可以通过执行类似的操作使该代码在变更检测之外运行。

ngOnInit(){
  this.ngZone.runOutsideAngular(() => {    
     this.interval = window.setInterval(() => {
      this.eventService.on(ApplicationEvents.SHOW_FULL_PAGE_LOADER, (value) => {
      this.viewModel.showLoader = value;
      });
  }, 1)});
};
于 2021-05-01T07:01:07.207 回答