加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

角度 – markForCheck()和detectChanges()之间有什么区别?

发布时间:2020-12-17 07:48:08 所属栏目:安全 来源:网络整理
导读:在Angular中,ChangeDetectorRef.markForCheck()和ChangeDetectorRef.detectChanges()有什么区别? 我只有found information on S.O关于NgZone.run()之间的区别,但不是在这两个函数之间. 对于仅仅参考文献的答案,请说明一些实际的情景,选择一个?这将有助于在
在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;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读