zoukankan      html  css  js  c++  java
  • Angular:OnPush变化检测策略介绍

    在OnPush策略下,Angular不会运行变化检测(Change Detection ),除非组件的input接收到了新值。接收到新值的意思是,input的值或者引用发生了变化。这样听起来不好理解,看例子:
    子组件接收一个balls(别想歪:))输入,然后在模板遍历这个balls数组并展示出来。初始化2秒后,往balls数组push一个new ball

    //balls-list.component.ts
    @Component({
      selector: 'balls-list',
      template: `
        <div *ngFor="let ball of balls">{{ball}}</div>
      `
    })
    export class BallsList implements OnInit{
      @Input() balls: any[];
      ngOnInit(){
        setTimeout(() => {
          this.balls.push('new ball');
        },2000)
      }
    }
    

    注意:因为鼠标键盘事件会触发变化检测,所以这里使用定时器!
    现在是不使用OnPush策略的情况。2秒后,new ball就被添加到视图中了。
    当使用OnPush变化检测策略的时候,new ball并不会被添加到视图中:

    //balls-list.component.ts
    @Component({
      selector: 'balls-list',
      template: `
        <div *ngFor="let ball of balls">{{ball}}</div>
      `,
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class BallsList implements OnInit{
      @Input() balls: any[];
      ngOnInit(){
        setTimeout(() => {
          this.balls.push('new ball');
        },2000)
      }
    }
    

    但是,如果在父组件改变input的值,视图是会更新的,因为这样Angular会运行变化检测:

    //app.component.ts
    @Component({
      selector: 'my-app',
      template: `
        <balls-list [balls]="balls"></balls-list>
        <button (click)="changeRef()">Change Ref</button>
      `,
    })
    export class AppComponent implements OnInit{
      balls: any[] = ['basketball','football'];
      ngOnInit(){}
      changeRef(){
        this.balls = ['baseball','pingpong'];
      }
    }
    

    这样就相当于改变了balls的引用。
    但是,如果不改变balls的引用,只给它push一个值,视图是不会更新的:

    //app.component.ts
    @Component({
      selector: 'my-app',
      template: `
        <balls-list [balls]="balls"></balls-list>
        <input #input>
        <button (click)="addBall(input.value)">Add a ball</button>
      `,
    })
    export class AppComponent implements OnInit{
      balls: any[] = ['basketball','football'];
      ngOnInit(){}
      addBall(ball){
        this.balls.push(ball);
      }
    }
    

    这时如果有需要,我们可以用ChangeDetectorRef.detectChanges()手动触发变化检测。
    这样解释应该很清楚了!

    提示:OnPush配合Immutable.js使用效果更佳!

    本文代码和演示可以在这里查看(建议电脑访问,自备梯子)。
    不当之处欢迎指出,欢迎交流!

  • 相关阅读:
    如今我这样编程,你呢?
    专注UI——是alert()打败了你!
    创业公司十分钟简单搭建GIT私有库
    小胖说事22-----iOS开发技巧之取消键盘响应和截屏功能
    C++运算符重载的妙用
    汽水瓶
    Android 应用按返回键异常退出的问题
    053第256题
    Activity、FragmentActivity和AppCompatActivity的区别
    Android中Activity和AppcompatActivity的区别(详细解析)
  • 原文地址:https://www.cnblogs.com/cme-kai/p/8497146.html
Copyright © 2011-2022 走看看