4-17 脏值检测(3)

那么有没有一种情况,就是真的需要在ngAfterViewChecked里面赋值?

我们需要导入ngZone。这是Zone.js这个第三方的类库提供的

Zone是浏览器的js运行时,我们会在浏览器中划分N个区域,每个区域运行自己的程序,彼此相互不干扰。这样的话,angular本身运行在一个angular的zone中,那么如果我们可以把这个值让angular这个zone不知道,也就是运行在angular的Zone之外。那么这个脏值监测就监测不到这个值的改变。那么我们就可以把脏值监测绕过去。

在angular之外运行title复制的这句话。当然光这么写还不行。

angular检查的是title这个属性,是一个同步操作。下面一旦改变了之后,还是会监测到。要让title这个属性返回的值是不变的

那么我们就需要异步的,异步的去改变这个值,


这样它同步的去找tilte()这个值,检查的时候其实这个值是不变的。因为下面是异步操作去改变它的值。同步检查是在前面,所以他检查两遍得到的值 都是同一个值。


这样浏览器上 异常就没了

那么什么具体的场景会触发这样一个需求呢?
比如说我们现在想做一个倒计时,比如我们这里做一个管道。


这样就会报错,因为每次检查,这个值都是不一样的。因为这个值我第一次检查的时候是一个值,第二次检查的时候,这个值就变了。

做一个变量time



缺一个触发的事件。添加触发脏值监测的方法

函数先什么都不做



点一下时间出来了。触发了脏值监测。

再点一次又触发


我们持续性的变化是在angular之外做的

倒计时

想让时间持续性的变化,这种情况下直接操作dom会效率高一些。因为绑定它不是没有代价的。代价就是脏值监测的形式监测值的改变。然后去更新这个html
用#来做一个引用。

用ViewChild去引用timeRef这个模块。它的类型是一个静态类型。没有在ngIf或者是ngFor当中。

类型是ElementRef





一直在变化。而且这样不会引发脏值监测。也不会有性能的一些损失。




这样直接的操作dom是有一定的问题的。再注入Render2






ts类里面使用管道

在angular6之上的版本

fformatDate函数其实就是管道的变化函数。






实时变化

下一节

在确定要使用脏值监测的时候,如何提高性能。就是通过onPush
在组件的装饰器里面,





这样设置以后,它就只看装饰器的属性,这些属性变了,就会隐藏脏值监测。这样就成了一个纯粹性的木偶组件,或者叫做笨组件。

这里也加上



这样这三个组件,只有在他们自己的input属性改变的时候 才会引发脏值监测。而且它引发的是他们这一个分支的,我们不会跑整个的树,只会跑这一个分支的树。所以它范围就会小很多。

以上几个配置改变后,对我们的程序并没有什么影响

如果我们也让他变成onPush的 

先到男装,再切回来 ,切不回来了

路径参数的变化,在默认的路由策略之下,不会销毁这个组件,它是重用这个组件。

所以这个ngOnInit只走了一遍。

当然只走一遍,其实问题也并不大,因为在这里面,我们是订阅了这个参数的变化,在这里去赋值的。异步的方法去赋值的。

但是现在变成了 change on Push


由于这里并没有input类型的参数。

所以这个变化被忽略掉了,系统并没有监测到它

处理

那么这种情况下我们如何处理呢?需要一些手动的技巧。
注入

 

手动的去触发,告诉angular这里发生了变化了

这个时候再切换就没有问题了。



这是一个常用的小技巧。

结束

 

posted @ 2020-08-30 00:27  高山-景行  阅读(197)  评论(0编辑  收藏  举报