考虑以下code
2.0.3
根据我的实验,这是我对当前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
添加到组件中。行为更改如下
我。如果组件内的变量具有引用更改,则重新呈现该组件,并检查子组件的更改检测(其特定的更改检测算法值/引用检查取决于ChangeDetectionStrategy.OnPush
)
II。如果组件内部的变量没有引用更改,则不会重新呈现该组件,并且不检查子组件的更改检测,无论是否存在ChangeDetectionStrategy.OnPush
这是正确的解释吗?
答案 0 :(得分:4)
我稍稍改造了你的傻瓜:new plunker
由于原始值为immutable,重新分配和更新之间没有区别 - 原语获取新的不可变值,因此我删除了“更新”代码。此外,拆分分配新的对象引用(触发更改检测)和分配新的原始值(不触发更改检测)非常有用。所以我也这样做了。
如果您运行我的Plunker,我们可以进行以下观察:
OnPush
组件上更改引用类型的输入属性
将更新组件的视图。检查模板绑定的更改。此外,还会检查子组件(假设它们未使用OnPush
)。OnPush
组件上的引用类型中包含的原始属性不会更新组件的视图。不检查模板绑定的更改。此外,不检查子组件,无论它们是否使用OnPush
。ngDoCheck()
始终在第一个OnPush
组件上调用,无论是否检查模板绑定是否发生更改。我发现这很奇怪(谁知道,也许这是一个错误)。因此,仅仅因为调用ngDoCheck()
并不一定意味着检查模板绑定。注意,当检测到模板绑定更改时,只将该更改传播到子组件或DOM(视情况而定,具体取决于绑定类型)。如果绑定更改导致DOM更改,则不会重新呈现整个组件。只更新了绑定的DOM数据,浏览器才会更新那个DOM元素。 (这与其他一些框架不同,如果发现任何更改,它们会重新渲染整个模板。这有助于使Angular更快。)
答案 1 :(得分:0)
这篇文章详细解释了它:
http://victorsavkin.com/post/133936129316/angular-immutability-and-encapsulation
简而言之,您的假设是正确的。 Angular2必须保守并检查价值相等,即它必须进行深度检查&#39;引用的对象。
使用ChangeDetectionStrategy.OnPush
时,只有在对其输入对象的引用发生更改时才会更新组件。
这就是为什么不可变对象可以是首选数据结构 - 如果我们必须更新对象,该组件现在引用一个新对象。因此,角度很容易知道哪些组件必须更新。
通过ChangeDetectorRef.markForCheck();
方法,可以通过观察者实现高性能行为。
这在此解释:
http://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html