ChangeDetectorRef.markForCheck()和 和有什么不一样ChangeDetectorRef.detectChanges()?
ChangeDetectorRef.markForCheck()
ChangeDetectorRef.detectChanges()
对于仅参考文档的答案,请说明一些实际场景以选择其中一个。
检测变化():无效 检查变化检测器及其子代。
检测变化():无效
检查变化检测器及其子代。
这意味着,如果您的模型(您的类)中的任何东西发生了变化,但没有反映视图,您可能需要通知 Angular 来检测这些更改(检测本地更改)并更新视图。
可能的情况可能是:
1- 变化检测器从视图中分离(见分离)
2- 发生了更新,但尚未在 Angular 区域内,因此,Angular 不知道它。
就像第三方功能更新了您的模型并且您想在此之后更新视图一样。
someFunctionThatIsRunByAThirdPartyCode(){ yourModel.text = "new text"; }
因为此代码在 Angular 的区域之外(可能),您很可能需要确保检测到更改并更新视图,因此:
myFunction(){ someFunctionThatIsRunByAThirdPartyCode(); // Let's detect the changes that above function made to the model which Angular is not aware of. this.cd.detectChanges(); }
注意 :
还有其他方法可以使上述工作,换句话说,还有其他方法可以将更改带入 Angular 更改周期。
** 您可以将该第三方函数包装在 zone.run 中:
myFunction(){ this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode); }
** 您可以将函数包装在 setTimeout 中:
myFunction(){ setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0); }
3- 在某些情况下,您会在change detection cycle完成后更新模型,在这些情况下,您会遇到这个可怕的错误:
change detection cycle
“检查后表达式发生了变化”;
这通常意味着(来自 Angular2 语言):
我看到您的模型发生了变化,这是由我接受的一种方式(事件、XHR 请求、setTimeout 和…)引起的,然后我运行了更改检测以更新您的视图并完成了它,但随后还有另一个您的代码中的函数再次更新了模型,我不想再次运行我的更改检测,因为不再有像 AngularJS 这样的脏检查:D,我们应该使用一种方式的数据流!
你肯定会遇到这个错误:P。
修复它的几种方法:
1- 正确的方式 :确保更新在更改检测周期内(Angular2更新是一种发生一次的方式流程,之后不要更新模型并将代码移动到更好的位置/时间)。
2- 懒惰的方式 :在更新之后运行 detectChanges() 以使 angular2 开心,这绝对不是最好的方式,但是当你问什么是可能的场景时,这是其中之一。
你这样说:我真诚地知道你运行了更改检测,但我希望你再做一次,因为在你完成检查后我必须即时更新一些东西。
3-将代码放在asetTimeout中,因为setTimeout由区域修补并detectChanges在完成后运行。
setTimeout
detectChanges
从文档
markForCheck() : void 将所有 ChangeDetectionStrategy 祖先标记为要检查。
markForCheck() : void
将所有 ChangeDetectionStrategy 祖先标记为要检查。
当您的组件的ChangeDetectionStrategy 为 OnPush 时,这主要是需要的。
OnPush 本身意味着,仅在发生任何这些情况时才运行更改检测:
1- 如果@Input 属性的引用完全改变,则组件的@inputs 之一已完全替换为新值,或者简单地说。
因此,如果您的组件的 ChangeDetectionStrategy 是 OnPush ,那么您有:
var obj = { name:'Milad' };
然后你像这样更新/变异它:
obj.name = "a new name";
这不会更新 obj 引用,因此不会运行更改检测,因此视图不会反映更新/突变。
在这种情况下,您必须手动告诉 Angular 检查和更新视图(markForCheck);
所以如果你这样做:
你需要这样做:
this.cd.markForCheck();
相反,下面会导致更改检测运行:
obj = { name:"a new name" };
它完全用新的 obj 替换了以前的 obj {};
{}
2- 触发了一个事件,例如单击或类似的事情,或者任何子组件发出了一个事件。
像这样的事件:
简而言之:
detectChanges()当您在 Angular 运行更改检测后更新模型时使用,或者如果更新根本不在 Angular 世界中。
detectChanges()
如果您正在使用markForCheck()OnPush 并且您ChangeDetectionStrategy通过改变一些数据来绕过,或者您已经在 setTimeout 中更新了模型,请使用该选项;
markForCheck()
ChangeDetectionStrategy