angular - 即使输入未更改,DOM 也会在更改检测周期期间使用 OnPush 策略更新视图
问题描述
也许我在 Angular 的变更检测机制中遗漏了一些东西。
我有 2 个组件:
应用组件。
@Component({
selector: 'my-app',
template: `
<button
(click)="0">
Async Action in Parent
</button>
<child
[config]="config">
</child>
<button
(click)="mutate()">
Mutate Input Object
</button>
`
})
export class AppComponent {
config = {
state: 0
};
mutate() {
this.config.state = 1;
console.log(this.config.state);
}
}
和子组件
@Component({
selector: "child",
template: `
<h1>{{config.state}}</h1>
<button
(click)="0">
Async Action in Child
</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent {
@Input() config;
ngDoCheck() {
console.log(`Check`);
}
}
第1步。
在这里,单击一个按钮时,AppComponent
我调用mutate
函数,该函数反过来改变传递给嵌套的对象ChildComponent
。
第2步。
然后我单击同一按钮中的另一个按钮,AppComponent
以触发更改检测循环。由于ChildComponent
正在使用的OnPush
策略和输入参考没有改变,因此在接下来的变化检测中 没有检查ChildComponent
视图并且没有更新DOM 插值。到目前为止,它的行为符合我的预期。
但是,如果在第 2 步。我从内部触发更改检测ChildComponent
(通过单击适当的按钮),则 检查ChildComponent
视图并更新DOM 插值。为什么会这样?自上次以来没有任何变化。
这是 StackBlitz 上的演示。
我读过Maxim Koretskyi的一篇关于变更检测的精彩文章,但不幸的是它没有回答我的问题。
解决方案
触发组件中的 onpush 更改检测的事情(除了输入更改)包括输出事件,这是 click 指令绑定,以及所有其他用户交互指令绑定(滚动、鼠标悬停等)。组件内的超时、间隔或承诺解决方案以及异步管道也是如此。Angular 无法知道输出事件或任何实际更改的内容,因此它假定它确实更改了并运行更改检测周期。
推荐阅读
- ios - 如何在 iOS 上获取照片库中图像的拍摄位置(不是 GPS 坐标)?
- javascript - Javascript Pomodoro Timer - 暂停/播放/一般功能
- android - 如何在滚动时修复 ConstraintLayout 中的视图?
- labview - 进入Button控件元素时程序会调用多少次递增函数
- css - 使用 CSS 创建两栏式杂志布局
- java - 如何使用hibernate创建一个新的oracle数据库
- c++ - QLabel 上的绘图点出错
- database - 用 Java 读取大型 .sql 文件并将数据写入数据库。
- angular - 如何在 events.addUserLoaded Angular 6 中重定向
- html - Bootstrap 如何使模态外部可以滚动和模态固定?