生命周期钩子被称为变化检测的一部分 . 如果要监视的组件数据是原始输入属性(String,boolean,number),则可以实现 ngOnChanges() 以通知更改 . 如果input属性是引用类型(对象,数组等),但是引用didn 't change (e.g., you added an item to an existing array), you' ll需要实现 ngDoCheck() (有关此内容的更多信息,请参见this SO answer) . 您应该只更改违反该组件的组件's properties and/or properties of descendant components (because of the single tree walk implementation -- i.e., unidirectional data flow). Here' s a plunker . 有状态的管道也可以trip you up在这里 .
7 回答
在Angular 2中,更改检测是自动的...
$scope.$watch()
和$scope.$digest()
R.I.P.不幸的是,开发指南的“更改检测”部分尚未编写(Architecture Overview页面底部附近有一个占位符,位于"The Other Stuff"部分) .
以下是我对变更检测如何工作的理解:
Zone.js "monkey patches the world" - 它拦截浏览器中的所有异步API(当Angular运行时) . 这就是为什么我们可以在我们的组件中使用
setTimeout()
而不是$timeout
...因为setTimeout()
是猴子修补的 .Angular构建并维护"change detectors"的树 . 每个组件/指令有一个这样的变化检测器(类) . (您可以通过注入ChangeDetectorRef来访问此对象 . )这些更改检测器是在Angular创建组件时创建的 . 它们会跟踪所有绑定的状态,以便进行脏检查 . 从某种意义上说,这些类似于Angular 1为
{{}}
模板绑定设置的自动$watches()
.与Angular 1不同,变化检测图是一个有向树,不能有循环(这使得Angular 2的性能更高,我们将在下面看到) .
当事件触发时(在Angular区域内),我们编写的代码(事件处理程序回调)运行 . 它可以更新它想要的任何数据 - 共享应用程序模型/状态和/或组件的视图状态 .
之后,由于添加了挂钩Zone.js,它然后运行Angular的变化检测算法 . 默认情况下(即,如果您未在任何组件上使用
onPush
更改检测策略),树中的每个组件都将从顶部按深度优先顺序检查一次(TTL = 1) . (好吧,如果您处于开发模式,更改检测会运行两次(TTL = 2) . 有关详细信息,请参阅ApplicationRef.tick() . )它使用这些更改检测器对象对所有绑定执行脏检查 .生命周期钩子被称为变化检测的一部分 .
如果要监视的组件数据是原始输入属性(String,boolean,number),则可以实现
ngOnChanges()
以通知更改 .如果input属性是引用类型(对象,数组等),但是引用didn 't change (e.g., you added an item to an existing array), you' ll需要实现
ngDoCheck()
(有关此内容的更多信息,请参见this SO answer) .您应该只更改违反该组件的组件's properties and/or properties of descendant components (because of the single tree walk implementation -- i.e., unidirectional data flow). Here' s a plunker . 有状态的管道也可以trip you up在这里 .
对于找到的任何绑定更改,将更新组件,然后更新DOM . 变更检测现已完成 .
浏览器通知DOM更改并更新屏幕 .
其他参考资料了解更多:
Angular’s $digest is reborn in the newer version of Angular - 解释AngularJS中的想法如何映射到Angular
Everything you need to know about change detection in Angular - 非常详细地解释了变化检测如何在引擎盖下工作
Change Detection Explained - 尽管有关博客2016年2月22日 - 可能是最好的参考资料
Savkin的Change Detection Reinvented视频 - 绝对要看这个
How does Angular 2 Change Detection Really Work? - jhade的博客2016年2月24日
关于Zone.js的
Brian's video和Miško's video Brian 's is about Zone.js. Miško'是关于Angular 2如何使用Zone.js来实现更改检测 . 他还谈到了一般的变化检测,以及一些关于
onPush
的讨论 .Victor Savkins博文:Change Detection in Angular 2,Two phases of Angular 2 applications,Angular, Immutability and Encapsulation . 他很快就覆盖了很多地方,但他有时会很简洁,而你却在挠头,想知道丢失的碎片 .
Ultra Fast Change Detection(Google doc) - 非常技术性,非常简洁,但它描述/草绘了作为树的一部分构建的ChangeDetection类
此行为现在是组件生命周期的一部分 .
组件可以在OnChanges接口中实现ngOnChanges方法以访问输入更改 .
例:
如果除了自动双向绑定之外,您希望在值更改时调用函数,则可以将双向绑定快捷方式语法分解为更详细的版本 .
<input [(ngModel)]="yourVar"></input>
是简写
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(参见例如http://victorsavkin.com/post/119943127151/angular-2-template-syntax)
你可以这样做:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
您可以使用
getter function
或get accessor
作为角度2的监视 .见demo here .
这是另一种使用模型的getter和setter函数的方法 .
如果你想使它成双向绑定,你可以使用
[(yourVar)]
,但你必须实现yourVarChange
事件并在每次变量变化时调用它 .像这样追踪英雄变化
然后当你的英雄变了,请拨打
this.heroChange.emit(this.hero);
[(hero)]
绑定将为您完成剩下的工作看这里的例子:
http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview
试试这个应用 still 要求
$parse
,$eval
,$watch
喜欢Angular中的行为https://github.com/vinayk406/angular-expression-parser