我正在构建一个包含许多组件的Angular 4应用,其中ChangeDetectionStrategy
为OnPush
。虽然the Angular Documentation on the matter没有太多信息,但各种消息来源表示OnPush
个组件仅在其@Input
更改时更新(新对象或基元)。
但是,OnPush
组件内的各种事件似乎也会触发变更检测。但是,我注意到其他人没有触发变化检测。
ChangeDetectionStrategy.OnPush
关于组件内事件的具体规则是什么?
答案 0 :(得分:1)
来自Change Detection Strategy: OnPush,
这将告知Angular我们的组件仅依赖于它的输入,并且传递给它的任何对象都应该被认为是不可变的。
它继续表明属性更改不会触发更改检测(被认为是不可变的),但对对象本身的更改会触发更改检测。
所以看起来关键标准是不变性。模板上引用的对象的更改触发器为
我没有测试过一个可观察的变化,但是在别处作为触发器给出了变化。 (可观察的发射会更改对象引用,而不是它的属性)。
使用角度版 5.2.0-beta.1
进行测试扩展RangleIO示例
帖子顶部引用的RangleIO页面有一个Plunker,它说明通过Input()
参数传递给组件的对象被认为是不可变的。子组件的更改检测器不会响应输入对象属性的更改。
但是,在复制了 中的更改按钮后,可以看到在组件自己的代码中调用的对象属性更改将改变它的视图。
以下是代码Plunker
<强> movie.component.ts 强>
@Component({
selector: 'app-movie',
styles: ['div {border: 1px solid black}'],
template: `
<div>
<h3>{{ title }}</h3>
<p>
<label>Actor:</label>
<span>{{actor.firstName}} {{actor.lastName}}</span>
</p>
<button type="button" (click)="changeActorProperties()">
Inside Movie Component - Change Actor Properties (will change view)
</button>
<button type="button" (click)="changeActorObject()">
Inside Movie Component - Change Actor Object (will change view)
</button>
</div>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MovieComponent {
@Input() title: string;
@Input() actor: Actor;
changeActorProperties(): void {
this.actor.firstName = 'Nicholas';
this.actor.lastName = 'Cage';
}
changeActorObject(): void {
this.actor = new Actor('Bruce', 'Willis');
}
}
<强> app.component.ts 强>
@Component({
selector: 'app-root',
template: `
<h1>MovieApp</h1>
<p>{{ slogan }}</p>
<button type="button" (click)="changeActorProperties()">
Outside Movie Component - Change Actor Properties (will not change Movie view)
</button>
<button type="button" (click)="changeActorObject()">
Outside Movie Component - Change Actor Object (will change Movie view)
</button>
<app-movie [title]="title" [actor]="actor"></app-movie>`
})
export class AppComponent {
slogan = 'Just movie information';
title = 'Terminator 1';
actor = new Actor('Arnold', 'Schwarzenegger');
changeActorProperties(): void {
this.actor.firstName = 'Nicholas';
this.actor.lastName = 'Cage';
}
changeActorObject(): void {
this.actor = new Actor('Bruce', 'Willis');
}
}
答案 1 :(得分:1)
ChangeDetectionStrategy.OnPush
时触发更改检测的事件的若干说明:
OnPush变化检测器在其他几个中被触发 除了组件Input()引用的更改之外的其他情况,它也是 被触发例如:
- 如果组件事件处理程序被触发
- 如果通过异步管道链接到模板的observable发出新值
他们添加了以下建议:
因此,如果我们记得尽可能多地订阅任何观察者 使用模板级别的异步管道,我们得到了几个 优点:
- 我们将使用OnPush
来减少更改检测问题- 我们会的 从默认的更改检测切换更容易 如果我们需要
,稍后会对OnPush采取策略- 不可变数据和@Input() 参考比较不是实现高性能的唯一方法 使用OnPush的UI:反应式方法也是使用OnPush的选项 有效
在问题&#34; {Angular 2&#34;在Victor,Viktor Savkin解释说:
使用OnPush探测器时,框架将检查OnPush 组件在其任何输入属性发生更改时,触发时 事件,或当一个观察者发射事件时。