考虑以下code

import {Component, OnInit, Input, OnChanges, DoCheck, ChangeDetectionStrategy} from 'angular2/core'

@Component({
  selector: 'child1',
  template: `
    <div>reference change for entire object: {{my_obj1.name}}</div>
    <div>reassign primitive in property of object: {{my_obj2.name}}</div>
    <div>update primitive in property of object: {{my_obj2.num}}</div>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class Child1 {

  @Input()
  my_obj1: Object = {'name': ''};

  @Input()
  my_obj2: Object = {'name': '', 'num': 0};

  ngDoCheck() {
    console.log('check from child1');
    console.log(this.my_obj1);
    console.log(this.my_obj2);
  }
}

@Component({
  selector: 'parent',
  template: `
    <div>
      <child1
        [my_obj1]="my_obj1"
        [my_obj2]="my_obj2"
      >
      </child1>
      <button (click)="change_obj1()">
        Change obj1
      </button>

    </div>
    `,
  directives: [Child1]
})
export class App {

  my_obj1: Object = {'name': 'name1'};
  my_obj2: Object = {'name': 'name2', 'num': 0};

  change_obj1() {
    this.my_obj1 = {'name': 'change1'}
    this.my_obj2['name'] = 'change2';
    this.my_obj2['num'] += 1;
  }
}

从我所做的实验来看,这是我对当前变化检测策略的理解,如果它是真的,有人能验证它吗?
默认情况下,angular2在执行更改检测时检查值是否相等。如果没有Angular2,则检查组件树中每个被监视的变量的值是否相等。如果值相等为false,则该特定组件将被重新提交;如果值相等为true,则该特定组件将不被重新提交。
如果将ChangeDetectionStrategy.OnPush添加到组件。行为变化如下
i.如果组件中的变量有引用更改,则重新提交组件,并检查子组件是否进行更改检测(其特定的更改检测算法值/引用检查取决于ChangeDetectionStrategy.OnPush
二。如果组件中的变量没有引用更改,则不会重新提交组件,也不会检查子组件是否进行更改检测,无论是否存在ChangeDetectionStrategy.OnPush
这是正确的解释吗?

最佳答案

我重新设计了一下你的小玩意儿:new plunker
由于原语值immutable,重新分配和更新没有区别-原语得到新的不可变值,所以我删除了“更新”代码。另外,分割分配新的对象引用(它会触发更改检测)和分配新的原语值(它不会触发更改检测)也是非常有帮助的。所以我也这么做了。
如果运行myPlunker我们可以进行以下观察:
更改OnPush组件上的引用类型的输入属性
将更新组件的视图。检查模板绑定是否有更改。此外,还会检查子组件(假设它们没有使用OnPush)。
更改OnPush组件的引用类型中包含的基元属性不会更新组件的视图。不检查模板绑定的更改。此外,不检查子组件,无论它们是否使用OnPush
ngDoCheck()始终在第一个OnPush组件上调用,无论是否检查模板绑定以进行更改。我觉得这很奇怪(谁知道呢,也许是虫子)。因此,仅仅因为调用了ngDoCheck()并不一定意味着检查了模板绑定。
注意,当检测到模板绑定更改时,仅将该更改传播到子组件或dom(视情况而定,具体取决于绑定类型)。如果绑定更改导致dom更改,则不会重新提交整个组件。只更新绑定的dom数据,浏览器将只更新该dom元素。(这与其他一些框架不同,在其他框架中,如果发现任何更改,它们会重新提交整个模板。这有助于加快角度。)

09-16 07:41