美文网首页
11Angular变更检测

11Angular变更检测

作者: learninginto | 来源:发表于2020-12-23 10:01 被阅读0次

    Angular中的变更检测机制是当component状态有变化的时候,angular都能检测到这些变化,并且能够将这些变化反应到页面上。

    作为框架,这个在我们看来是理所应当的,其实在angular内部涉及到很多复杂的操作,包括:变化检测、脏数据检查、数据绑定、单向数据流、更新DOM、NgZone等。
    我们知道Angular应用和Vue/React本质上是一棵组件树,变更检测都是沿着组件树从root组件开始至上而下执行的,所以上面变更检测机制涉及的很多操作和属性都是组件级的,下面分别说明:

    触发变更检测的时机
    1. DOM事件:页面的click、submit、mousedown……
    1. XHR:从后端服务器拿到数据
    1. Timers:setTimeout()、setInterval()
    单项数据流
    单项数据流.png

    假设其中某个组件中触发了变更检测,就会从根组件开始,从上至下排着检测一遍,并且已经检测完的组件,不允许再被子组件修改

    在子组件中修改了值,虽然会报错,但仍显示的是变更之后的结果。

    Expression has changed after it was checked.
    
    onPush策略
    onPush.png

    如果设置了onPush变更检测策略,则变更检测器仅在显式调用它,或由@Input引用的变化或触发事件处理程序时运行,以提高性能。

    • onPush策略后触发变更检测的时机
    1. DOM事件:页面的click、submit、mousedown……等dom事件
    2. 组件的@Input引用发生变化
    3. Observable订阅事件,同时设置了Async pipe
    4. 手动使用ChangeDetectorRef.markForCheck()、ApplicationRef.tick()方法

    阻断了一个组件的变更检测后,它和它的子组件都不会检测了

    ChangeDetectorRef

    从变更检测树中添加或移除视图、初始化变更检测并显示地把这些视图标记为脏的,意思是它们变了,需要重新渲染。

    constructor(private cdr:ChangeDetectorRef){
        this.cdr.detach();
    }
    
    • detach()

    从变更检测树中分离开视图,已分离的视图在重新附加上去之前不会检查。与detectChanges()结合使用,可以实现局部变更检测

    • reattach()

    把以前分离开的视图重新附加到变更检测树上。

    • markForCheck()

    在onPush中,通过定时器触发变更检测,要引入ChangeDetectorRef,使用markForCheck将视图显示地标记为已更改,以便它再次进行检查。

    constructor(private cdr:ChangeDetectorRef){}
    ngOninit(){
        setTimeout(() => {
            this.cdr.markForCheck();
        })
    }
    
    • detectchanges()

    检查该视图与子视图

    • 至此,我们在后面的创建的组件中,统一都采用OnPush策略,犹如Ant Design of Angular官网描述的一般:支持 OnPush 模式,性能卓越。
      image.png
    @Component({
        changeDetection:ChangeDetectionStrategy.OnPush
    })
    
    • 创建组件时,直接声明为onPush模式
    ng g c components -s -skipTests -c OnPush
    

    相关文章

      网友评论

          本文标题:11Angular变更检测

          本文链接:https://www.haomeiwen.com/subject/ncrynktx.html