绑定到函数时如何触发角度变化检测?

Posted

技术标签:

【中文标题】绑定到函数时如何触发角度变化检测?【英文标题】:How Angular Change Detection is triggered when you are binding to a function? 【发布时间】:2018-08-25 12:31:03 【问题描述】:

来自这两个帖子:

The mechanics of DOM updates in Angular Angular 2 Performance: Is it better to bind with a data member than a function?

我了解发生“更改检测”时 DOM 是如何更新的。我从"Everything you need to know about change detection in Angular" 不明白的一点是 Angular 如何跟踪函数内部使用了哪些属性,因此何时应该运行“更改检测”。

假设这是父组件视图。

<child [prop]="func()"></child>

func() 在哪里

func()  return this.parentProp 

parentProp 尚未在模板中使用。如果parentProp 被服务更改,Angular 怎么知道func() 依赖于parentProp,因此应该触发“更改检测”并更新视图。

【问题讨论】:

【参考方案1】:

Angular 不知道也不关心函数的内容。

Angular 将在每次更改检测运行时调用func() 并比较之前的结果是否与当前结果相同。

因为调用函数并比较结果比仅仅比较之前的值和当前值要昂贵得多,所以最好使用事件来更新带有函数结果的属性并将视图仅绑定到属性,而不是of 直接传递给函数。

如果函数在后续调用中返回不同的值(使用相同的参数值),您将在开发模式下遇到异常,例如

模型自上次检查后发生了变化

【讨论】:

所以也许我的问题比这更基本。如果模板上没有出现的组件属性发生变化,是否会运行变更检测? 不是属性更改导致更改检测运行,而是更改检测检查属性是否已更改。何时运行更改检测取决于您的设置(例如通过设置 changeDetection: ChangeDetectionStrategy.OnPush)。更改检测通常发生在事件处理程序被调用并且其执行已完成(由 Angulars 区域识别)或被ChangeDetectorRef.markForCheck() 显式调用时。 使用 getter 方法而不是实际函数是否同样昂贵? 是的,都是一样的,只是语法有点不同。

以上是关于绑定到函数时如何触发角度变化检测?的主要内容,如果未能解决你的问题,请参考以下文章

未在 Router.navigate() 上触发角度变化检测

如何检测 DataGridView CheckBox 事件变化?

Vue如何检测数组变化

如何在 SwiftUI 中检测 TextField 的实时变化?

ngOnChanges无法检测数组内容修改时解决方案

Angular 1.6.4如何检测组件的无绑定属性的变化[重复]