为什么这个组件在这个简单的砰砰声中

@Component({
  selector: 'my-app',
  template: `<div>I'm {{message}} </div>`,
})
export class App {
  message:string = 'loading :(';

  ngAfterViewInit() {
    this.updateMessage();
  }

  updateMessage(){
    this.message = 'all done loading :)'
  }
}

扔:

例外:表达式'I'm {{message}} in App@0:5'在被检查后发生了变化。之前的值:'I'm loading:('。当前值:'I'm all done loading:)' in [I'm {{message}} in App@0:5]

当我所做的一切都是更新一个简单的绑定时,我的视图被启动?


当前回答

我有几乎相同的案例,我有一系列的产品。我不得不让用户删除产品根据他们的选择。最后,如果数组中没有产品,那么我需要显示取消按钮而不是返回按钮,无需重新加载页面。

我通过检查ngAfterViewChecked()生命周期钩子中的空数组来完成。 这就是我是如何做到的,希望它有帮助:)

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

products: Product[];
someCondition: boolean;

constructor(private cdr: ChangeDetectorRef) {}

ngAfterViewChecked() {
  if(!this.someCondition) {
    this.emptyArray();
  }
}

emptyArray() {
    this.someCondition = this.products.length === 0 ? true : false;

    // run change detection explicitly
    this.cdr.detectChanges();
}

removeProduct(productId: number) {
    // your logic for removing product.
}

其他回答

出现此错误是因为现有值在初始化后立即更新。所以如果你将更新新值后,现有的值在DOM中呈现,那么它将工作得很好。就像本文中提到的,Angular调试"表达式被检查后发生了变化"

比如你可以用

ngOnInit() {
    setTimeout(() => {
      //code for your new value.
    });

}

or

ngAfterViewInit() {
  this.paginator.page
      .pipe(
          startWith(null),
          delay(0),
          tap(() => this.dataSource.loadLessons(...))
      ).subscribe();
}

正如你所看到的,我没有在setTimeout方法中提到时间。因为它是浏览器提供的API,而不是JavaScript API,所以这将在浏览器堆栈中单独运行,并将等待调用堆栈项完成。

Philip Roberts在Youtube的一个视频中解释了浏览器API如何调用这个概念(什么是事件循环?)

你也可以试着把this.updateMessage();在ngOnInit下,像这样:

ngOnInit(): void { 
  this.updateMessage();
}

我从AfterViewInit切换到AfterContentChecked,它为我工作。

流程如下

在构造函数中添加依赖项: 构造函数(私有cdr: ChangeDetectorRef) {} 在实现方法代码中调用你的登录: ngAfterContentChecked () { this.cdr.detectChanges (); //调用或添加您的代码 }

我有同样的错误,我可以通过使用AfterViewInit和ChangeDetectionStrategy来解决它。OnPush

这是一篇详细的文章。 https://medium.com/@bencabanes/angular-change-detection-strategy-an-introduction-819aaa7204e7

你只需要在正确的生命周期钩子中更新你的消息,在这种情况下是ngAfterContentChecked而不是ngAfterViewInit,因为在ngAfterViewInit中对变量消息的检查已经开始但还没有结束。

看到的: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html !# afterview

所以代码就是:

import { Component } from 'angular2/core'

@Component({
  selector: 'my-app',
  template: `<div>I'm {{message}} </div>`,
})
export class App {
  message: string = 'loading :(';

  ngAfterContentChecked() {
     this.message = 'all done loading :)'
  }      
}

查看工作演示在Plunker。