当更改检测处于推送状态时,为什么属性更改仍会导致@Doput在ngDoCheck中发生变化?

时间:2017-10-19 01:05:32

标签: javascript angular typescript angular2-changedetection

考虑这个plunker

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'my-app-n1',
  template: `
    <my-app-n2 [from2]="from1"></my-app-n2>
    <div>
      {{from1.name}}
      <input type="button" value="n1"  (click)="changen1()">
    </div>
  `,
})
export class App2 {

  @Input() from1;

  ngDoCheck() {
    console.log('do check 1 ', this.from1);
  }

  ngOnChanges(changes: any) {
    console.log('n1 change ', changes);
  }  
  changen1() {
    this.from1 = {'name': 'name1-2'}
  }
}

@Component({
  selector: 'my-app',
  template: `
    <my-app-n1 [from1]="from"></my-app-n1>
    <input type="button" value="root" (click)="changen0()">
  `,
})
export class App {
  from: any;
  constructor() {
    this.from = {'name': 'name0'}
  }

  ngOnChanges(changes: any) {
    console.log('n0 change ', changes);
  }  

  changen0() {
    this.from.name = 'name-0-2-2'
  }

}

请注意App2使用ChangeDetectionStrategy.OnPush

点击changen0后,我希望不会调用ngOnChanges(因为没有分配新的引用),而ngDoCheck要调用this.from1来获取数据{ {1}},视图仍显示{'name': 'name0'}

但是

name0的调用ngDoCheck等于this.from1

,视图显示{'name': 'name-0-2-2'}

我的问题是以下

  1. 为什么属性name0已更改?

  2. 如果模型被更改,为什么视图与模型不一致?

1 个答案:

答案 0 :(得分:1)

您正在ChangeDetectionStrategy.OnPush使用App2,这意味着除非更新输入绑定App2,否则不会为[from1]="from"触发CD。

因此,当您在此处更新name属性时,name已更新:

changen0() {
    this.from.name = 'name-0-2-2'
}

您没有更新this.from的引用,因此App2没有触发更改检测,因此您没有看到HTML中的更改。 ngOnChanges也未被调用。

  使用this.from1等于{'name':'name-0-2-2'}

调用ngDoCheck

ngDoCheck并不意味着您的组件已被检查。当Angular检查父组件时调用它。阅读本文以获取更多信息: