angular回掉函数里数据修改视图不更新的问题解决

2019-10-6 一诺 angular

做angular项目中有时会遇到组件中的数据变化后视图中没有更新的问题
问题出现的场景:
可能是项目存在已久代码已不知所云、或者是陷入某个回调函数中、又或是使用了某个插件后。

先看下angular的变更检测策略:
Default :ng提供的Default的检测策略,只要组件的input发生改变,就触发检测;
OnPush :OnPush检测策略是input发生改变,并不立即触发检测,而是输入的引用发生变化时,才会触发检测。
ChangeDetectorRef.detectChanges():可显式的控制变更检测,在需要的地方使用即可;
NgZone.run():在整个应用中进行变更检测
ApplicationRef.tick():在整个应用中进行变更检测,侦听NgZone的onTurnDone事件,来触发检测

这个时候你就可以使用以下几种方法解决
1、查看组件中元数据中是否使用了
changeDetection: ChangeDetectionStrategy.OnPush
如果有,则说明该组件不使用变化检测,组件内所有数据变化都不会更新到视图
可以根据需求删除这句话或者在更新的数据后面加
this.changeDetectorRef.markForCheck();
如果不想每个更新数据的位置都加这句话那就删掉OnPush
若是还不好使,就看第二种方式
2、如果压根元数据中就没有使用OnPush(推荐方法
可以使用如下代码来解决
constructor(
     private changeDetectorRef: ChangeDetectorRef,
) {}
  在数据变化后不起作用的地方加上
 this.changeDetectorRef.detectChanges();
这样既可手动触发数据监测了
3、ngZone.run() 方法会导致整个应用程序发生更改检测(非必要不推荐使用)
constructor(
     private ngZone: NgZone
   ) {}
我们可以将某个要发生改变的变量或者方法直接放到ngZong.run()中。比如:
 this.ngZone.run(()=>{this.closeNum()})
 this.ngZone.run(()=>{this.uploadProgress})


如果在Angulars区域外运行的某些代码调用Angulars代码并更改状态,则需要明确调用更改检测,因为Angular无法知道状态发生了变化.

如果对状态的更改是组件的本地(例如组件字段),则ChangeDetectorRef.detectChanges或ChangeDetectorRef.markforCheck更有效.

如果来自外部的呼叫例如导航到不同的路由,这可能会对许多组件产生影响,并且还不清楚整个路由更改何时完成,因为它可能导致异步调用(以及调用回调).在这种情况下,zone.run()是更好的选项,因为直接和间接调用的代码(如observable和promises的回调)将在Angulars区域内运行,Angular将识别它们并自动调用更改检测

分享这篇文章
赞助鼓励:如果觉得内容对您有所帮助,您可以支付宝(左)或微信(右):

声明:如无特殊注明,所有博客文章版权皆属于作者,转载使用时请注明出处。谢谢!

发表评论:

皖ICP备15010162号-1 @2015 知向前端
qq:1614245331 邮箱:13515678147@163.com Powered by emlog