在Angular2中,每个级别组件的更改检测是否可以不同? 换句话说,如果我有
comp1 detection onPush
comp2 detection onPush
comp3 detection default
comp4 detection onPush
如果我对comp3应用更改,除非comp2更改,否则它是否会更新UI? 我问的原因是因为我看到一个奇怪的行为,我想也许是父母组件的错...
所以换句话说,你可以在组件树的差异级别检查ChangeDetection Strategies吗?并且通过zone.js的框架将足够智能,可以按照指定的值处理每个检测? (当我这样做时,我肯定会看到一些奇怪的更新行为..错误:未捕获尝试使用脱水检测器:UserInfo_0)
供参考:https://github.com/angular/angular/issues/6786 感谢
肖恩
答案 0 :(得分:4)
Pascal Precht的Eclilpse Nebula深入解释了Angular2变化检测。
根据我对解释的理解,除非comp2改变,否则确实不会检测到comp3的变化。事实上,除非comp2 和comp1 都发生变化,否则无法检测到它们。当组件使用推送更改检测策略标记时,除非组件的输入发生更改,否则会丢弃其整个子树。
然而,有一种解决方法,在博客文章的末尾附近详细说明。在comp3中,注入ChangeDetectorRef
并存储它。然后为任何导致comp3数据更改的事件设置处理程序,或者为数据本身使用Observable
,如果您还没有,则在该处理程序中调用{{1在markForCheck()
上。这将通知Angular2 comp3中的某些内容已经更改,并且下次更改检测运行时,它将检查从根到comp3的路径,无论是否有推送设置。
答案 1 :(得分:0)
所以为了让我解决这个问题,我必须首先关闭onPush检测才有意义,因为我在内部更新组件而不是通过其中一个输入:删除了changeDetection:ChangeDetectionStrategy.OnPush
但是,我还必须通过
强制进行变更检测constructor(private appStore:AppStore, private businessActions:BusinessAction, private ref:ChangeDetectorRef) {
....
updateUi() {
try {
this.ref.detectChanges();
} catch (e) {
}
}
我仍然不知道为什么我必须这样,因为我正在更新值的组件是一个子组件并在我的模板中指定,所以即使没有ref.detectChanges(),更改检测也应该启动...但这似乎解决了这个问题。我必须将它包装在一个catch中,以避免在导航时对已销毁的引用进行堆栈挂起调用...
并且鉴于我使用字符串作为我的子组件的输入并且JS中的字符串(基元)是不可变的,因此子组件应该更新其UI ...
希望这有助于某人...