ChangeDetectorRef.markForCheck()
有什么区别和 ChangeDetectorRef.detectChanges()
?
我只有found information on SO关于NgZone.run()
的区别,但不在这两个函数之间。
对于仅引用文档的答案,请举例说明一些实际情况以选择其中之一。
最佳答案
detectChanges() : void
这意味着,如果您的模型(您的类)中的任何内容发生了更改但未反射(reflect) View 的情况,您可能需要通知 Angular 检测这些更改(检测本地更改)并更新 View 。
可能的情况可能是:
1- 变更检测器从 View 中分离(见 detach)
2- 发生了更新,但它不在 Angular Zone 内,因此,Angular 不知道它。
就像当第三方函数更新了您的模型并且您想在此之后更新 View 时一样。
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
因为此代码在 Angular 的区域之外(可能),您很可能需要确保检测更改并更新 View ,因此: 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
之后更新模型的情况已完成,在这些情况下,您会收到这个可怕的错误:"检查后表达有变化";
这通常意味着(来自 Angular2 语言):
我看到您的模型发生了变化,这是由我接受的一种方式(事件、XHR 请求、setTimeout 和 ...)引起的,然后我运行了更改检测以更新您的 View 并完成了它,但是还有另一个您的代码中的函数再次更新了模型,我不想再次运行我的更改检测,因为不再像 AngularJS 那样进行脏检查:D,我们应该使用单向数据流!
你肯定会遇到这个错误 :P 。
修复它的几种方法:
1- 正道 :确保更新在变更检测周期内(Angular2 更新是发生一次的一种方式,之后不要更新模型并将代码移动到更好的位置/时间)。
2- 懒人方式 :在该更新之后运行detectChanges() 以使angular2 满意,这绝对不是最好的方法,但是当您询问可能的情况是什么时,这是其中之一。
这样你说:我真诚地知道你运行了更改检测,但我希望你再做一次,因为在你完成检查后我不得不动态更新一些东西。
3- 将代码放入
setTimeout
, 因为 setTimeout
由区域修补并将运行 detectChanges
完成后。从文档
markForCheck() : void
Marks all ChangeDetectionStrategy ancestors as to be checked.
这在 时最需要变更检测策略 您的组件是 OnPush .
OnPush 本身意味着,只有在发生以下任何一种情况时才运行更改检测:
1- 组件的@inputs 之一已完全替换为新值,或者简单地说,如果@Input 属性的引用完全更改。
所以如果 变更检测策略 您的组件是 OnPush 然后你有:
var obj = {
name:'Milad'
};
然后你更新/变异它像: obj.name = "a new name";
这不会更新 obj 引用,因此不会运行更改检测,因此 View 不会反射(reflect)更新/变异。在这种情况下,您必须手动告诉 Angular 检查和更新 View (markForCheck);
所以如果你这样做:
obj.name = "a new name";
你需要这样做: this.cd.markForCheck();
相反,下面会导致运行更改检测: obj = {
name:"a new name"
};
用新的 {}
完全取代了之前的 obj ;2- 事件已触发,例如单击或类似事件,或任何子组件已发出事件。
事件如:
简而言之:
detectChanges()
当您在 angular 运行后更新模型时,它会进行更改检测,或者如果更新根本不在 angular 世界中。markForCheck()
如果您使用 OnPush 并且绕过了 ChangeDetectionStrategy
通过改变一些数据或者你已经更新了 中的模型设置超时 ;关于angular - markForCheck() 和 detectChanges() 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364386/