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

@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]

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


当前回答

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

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

其他回答

我通过从angular core中添加ChangeDetectionStrategy来解决这个问题。

import {  Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'page1',
  templateUrl: 'page1.html',
})

只需将代码移动到要更改共享服务主题的组件的构造函数中

你只需要在正确的生命周期钩子中更新你的消息,在这种情况下是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。

我不能评论@Biranchi的帖子,因为我没有足够的声誉,但它为我解决了这个问题。

有一件事要注意! 如果添加changeDetection: ChangeDetectionStrategy。OnPush在组件上没有工作,它是一个子组件(哑组件)尝试添加到父组件也。

这修复了bug,但我想知道这有什么副作用。

出现此错误是因为现有值在初始化后立即更新。所以如果你将更新新值后,现有的值在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如何调用这个概念(什么是事件循环?)