角度 – markForCheck()和detectChanges()之间有什么区别?
在Angular中,ChangeDetectorRef.markForCheck()和ChangeDetectorRef.detectChanges()有什么区别?
我只有found information on S.O关于NgZone.run()之间的区别,但不是在这两个函数之间. 对于仅仅参考文献的答案,请说明一些实际的情景,选择一个?这将有助于在我的脑海中澄清.
来自文档:
detectChanges() : void Checks the change detector and its children. 如果您的模型(您的类)中的任何内容已更改但尚未反映视图的情况,则可能需要通知Angular才能检测到这些更改(检测本地更改)并更新视图. 可能的情况可能是: 1-变化检测器与视图分离(见detach) 2-更新已经发生,但它没有在角度区域内,因此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); } 在更改检测周期完成之后,还有更新模型的情况,在这些情况下,您会得到这个可怕的错误: “检查后表情已经改变”; 这通常意味着(来自Angular2语言): 我看到您的模型更新是由我接受的方式(事件,XHR请求,setTimeout和…)引起的,然后我运行我的更改检测更新您的视图,我完成了,但是另有一个在您的代码中更新模型的功能,我不想再次运行我的更改检测,因为没有像AngularJS这样的脏检查:D,我们应该使用单向数据流! 你一定会遇到这个错误:P. 几种方法来解决它: 1-正确的方法:确保更新在更改检测之内(Angular2更新是发生一次的一种方式,不要更新模型,然后将代码移动到更好的位置/时间). 2-懒惰的方式:在更新之后运行detectChanges(),以使angular2快乐,这绝对不是最好的方法,但是当你问什么是可能的情况,这是其中之一. 这样你说的是:我真诚地知道你运行了变更检测,但是我不能再做,因为在完成检查之后,我必须在飞行中更新一些东西. 3将代码放在setTimeout中,因为setTimeout被区域修补,并在完成后运行detectChanges. 从文档 markForCheck() : void Marks all ChangeDetectionStrategy ancestors as to be checked. 当组件的ChangeDetectionStrategy是OnPush时,这主要是需要的. OnPush本身就意味着,只有在发生这些情况时,才能运行更改检测: 1-组件的@inputs之一已经被一个新的值完全替换,或者简单地说,如果@Input属性的引用已经完全改变了. 所以如果您的组件的ChangeDetectionStrategy是OnPush,然后你有: var obj = { name:'Milad' }; 然后你更新/变更它像: obj.name = "a new name"; 这不会更新obj引用,因此更改检测不会运行,因此视图不会反映更新/突变. 相反,波纹管将导致更改检测运行: obj = { name:"a new name" }; 其中一个新的{}完全取代了以前的obj; 所以如果你改变了这个obj,那么这个视图不会被更新,即使你运行detectChanges也不会工作,因为没有根据ChangeDetectionStrategy.OnPush进行任何修改! 在这种情况下,您必须手动告知Angular才能检查并更新视图(markForCheck); 所以如果你这样做: obj.name = "a new name"; 你需要这样做: this.cd.markForCheck(); 2-事件已经触发了,像点击或者像这样的东西,或者任何一个子组件已经发出了一个事件. 活动如: >点击 简而言之: >使用detectChanges()更新模型后,角度已经运行它是更改检测,或者更新还没有在角度世界.>如果您使用OnPush,请使用markForCheck(),并且您通过突变某些数据或更新了setTimeout中的模型来绕过ChangeDetectionStrategy; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |