首页 文章

Angular - 同一组件中的ExpressionChangedAfterItHasBeenCheckedError

提问于
浏览
4

我有一个带有 HttpInterceptor 的简单 Angular 5 应用程序,它在发出请求时通知服务 . 组件可以订阅此服务以获取此信息 .

这里有错误的完整示例=> https://stackblitz.com/edit/angular-5b86se

在我的AppComponent中,我想在我的子组件(HelloComponent)中发出请求时显示加载指示符 .

import { Component } from '@angular/core';
import { LoadingIndicatorService } from './loading-indicator.service';

@Component({
  selector: 'my-app',
  template: `<div *ngIf="loading" style="color:red">pretend this is loading indicator</div>
<hello name="{{ name }}"></hello>`
})
export class AppComponent  {
  name = 'Angular 5';
   loading: boolean = false;

   constructor(private loadingIndicatorService: LoadingIndicatorService) { 

    loadingIndicatorService
      .onLoadingChanged
      .subscribe(isLoading => this.loading = isLoading);
  }
}

我收到以下错误:

错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后发生了变化 . 上一个值:'false' . 当前值:'true' .

如果我是正确的,当子组件更改父组件中的值时,会出现此错误 .

但我的子组件(HelloComponent)只执行HttpGet而 HttpInterceptor 正在通过具有observable的服务更改父组件(AppComponent) .

不应该更改服务是正确的解决方案吗?有人可以解释为什么这不起作用?

2 回答

  • 1

    它会抛出一个错误,因为在调用onLoadingChanged时,变量加载会更新 . 意味着你的初始值发生了变化 .

    我建议你阅读更多关于 **** here

    对此的一般修复是,

    constructor(private loadingIndicatorService: LoadingIndicatorService,private ref: ChangeDetectorRef) { 
        loadingIndicatorService.onLoadingChanged.subscribe(isLoading => {
           this.loading = isLoading
           this.ref.detectChanges();
        });
     }
    
  • -1

    AsyncPipe救援:

    <div *ngIf="loadingIndicatorService.onLoadingChanged | async">Loading...</div>
    

    请记住将服务更改为公开 .

    Edit: 还需要将changeDetectionStrategy设置为OnPush . 工作闪电战:https://stackblitz.com/edit/angular-ay1ikq

    至于为什么在没有OnPush的情况下即使使用AsyncPipe,也不能说 . 也许有人对Angular核心有深入的了解?在拦截器之前/之后内部触发CD?我几乎总是使用OnPush但是必须有一种我最初没有的情况,并且仍然没有看到AsyncPipe发生这种错误 . 唯一与我所做的事情完全不同的是使用拦截器做一些导致模板绑定值的变化,这是根本原因吗?

相关问题