• angular11源码探索[DoCheck 生命周期和onChanges区别]


    原理图

    直接生成模块和路由然后定义声明的模块

    ng g m  one --routing --m=app
    

    组件+模块+路由+指向的声明路径

    ng g m two --route=home  --m=app
    

    生命周期 DoCheck 和 onChanges 的区别

    当我们传入数组或者对象的时候,我们会发现子组件的onChanges 检测不到变化

    这时候我们可以用DoCheck 来监控变化了

    父组件,当点击的时候给父组件

    export class TwoComponent implements OnInit {
      public arr: Array<any> = ['a', 'b', 'c']
      obj: object = {
        name: 'xxx',
        age: 'bbb'
      };
    
      constructor() {
      }
    
    
      ngOnInit(): void {
      }
    
      public i: number = 0;
    
      clickMethod(): void {
        this.arr.push(this.arr.length)
        this.obj[this.i++] = this.i;
      }
    }
    
    <button (click)="clickMethod()">++</button>
    <app-user [sex]="arr" [videos]="obj"></app-user>
    

    子组件

    只要运行更改检测,就会调用 ngDoCheck()

    export class UserComponent implements OnInit,OnChanges,DoCheck {
      @Input('sex') sex;
      @Input('videos') videos;
     // 可以解构拿到需要修改的属性
      ngOnChanges({sex,videos}: SimpleChanges) {
        console.log(sex);
        console.log(videos);
      }
      ngDoCheck() {
        console.log(this.videos);
      }
    }
    

    我们会发现ngOnChanges子组件除了第一次传递的时候能监控到变化,当修改的时候监控不到

    但是我们会发现ngDoCheck 在修改的时候能监控到对象的变化

    ngOnChanges 用于 基本数据类型

    ngDoCheck 用于引用数据类型

    KeyValueDiffers

    KeyValueDiffers是不同地图差异策略的存储库。角内部使用它的指令NgClassNgStyle等等。无论何时,只要结合这些指令值的变化,这些变化体现。为了处理和更新更改,Angular使用KeyValueDiffers

    1. KeyValueDiffers可以使用构造函数注入到组件中。

    constructor(private kvDiffers: KeyValueDiffers) {} 
    

    2. KeyValueDiffers提供find方法。

        find(kv: any): KeyValueDifferFactory;
    

    kv:传递需要检测以进行更改的对象。
    find方法返回KeyValueDifferFactory

    3. KeyValueDifferFactory提供工厂KeyValueDiffer。要获取KeyValueDiffer实例,请KeyValueDifferFactory提供create方法。

        create<K, V>(): KeyValueDiffer<K, V>;
    

    4. KeyValueDiffer与众不同之处是跟踪对象随时间的变化。它具有一种diff计算先前状态和新对象状态之间的差异的方法。

        diff(object: Map<K, V>): KeyValueChanges<K, V> | null;
    

    5. KeyValueChanges自上次diff调用该方法以来,将更改保留在映射中。KeyValueChanges有以下方法。
    forEachItem:遍历所有更改。
    forEachPreviousItem:迭代已更改的先前项目。
    forEachChangedItem:迭代其值已更改的那些项。
    forEachAddedItem:遍历所有添加的项目。
    forEachRemovedItem:遍历所有已删除的项目。
    上述所有KeyValueChanges提供KeyValueChangeRecord项目的方法都是迭代的。

    6. KeyValueChangeRecord是表示项目更改信息的记录。KeyValueChangeRecord具有诸如currentValuepreviousValue。要获取当前值,我们将其称为currentValue属性,并获取先前值,我们将其称为previousValue属性。找到代码段。

        readonly key: K;
        readonly currentValue: V | null;
        readonly previousValue: V | null;
    

    完整的例子

    export class UserComponent implements OnInit, OnChanges, DoCheck {
      @Input('sex') sex;
      @Input('videos') videos;
      public differs
    
      // 可以解构拿到需要修改的属性,一般用于基本数据类型
      ngOnChanges({sex, videos}: SimpleChanges) {
        // console.log(sex);
        // console.log(videos);
      }
      ngDoCheck() {
        let mpArray = this.differs.diff(this.sex)
        if (mpArray) {
          // 变化检测
          mpArray.forEachAddedItem(record => {
            console.log('增加', record);
          })
          mpArray.forEachChangedItem(record => {
            console.log('更改', record);
          })
          mpArray.forEachRemovedItem(record => {
            console.log('删除', record);
          })
          /*有变动的时候,显示原始所有值*/
          mpArray.forEachPreviousItem(record => {
            // console.log('之前的',record);
          })
          /*遍历所有*/
          mpArray.forEachItem(record => {
            // console.log(record);
          })
        }
      }
    
      constructor(private kvDiffers: KeyValueDiffers) {
      }
    
      ngOnInit(): void {
        if (this.sex) {
          this.differs = this.kvDiffers.find(this.sex).create()
        }
      }
    
    }
    
    

    IterableDiffer

    跟踪随时间变化为可迭代的策略。用于通过NgForOf影响DOM中的等效更改来响应可迭代的更改

    在查看IterableDiffer 源码的时候我们会发现很多部分跟KeyValueDiffers 有重叠性,

    内部NgForOf使用了生命周期挂钩ngOnChangesngDoCheckngOnChanges该指令用于使用集合find实例的方法根据当前集合的类型选择一个差异IterableDiffersngDoCheck用于将差值应用于集合的当前值。在不同的是要收集与以前的值进行比较,并返回更改列表

    有趣的是,差异如何比较集合中的各个值。特别是,它使用值的哪些属性来区分它们。为此,我们需要看一下TrackByFunction界面

    代码

    export interface TrackByFunction<T> {
      (index: number, item: T): any;
    }
    

    demo

    <div *ngFor="let item of sex;trackBy:indexFn" >{{item}}</div>
    
    sex=['a','b','c']
    indexFn(index,item){
        console.log(index,item);
        return index
      }
    
    0 "a"
    1 "b"
    2 "c"
    

    不同点

    iterableDiffer 比较项目序列

    KeyValueDiffer 比较字典

  • 相关阅读:
    Linux进入单用户模式(passwd root修改密码)
    stark组件的分页,模糊查询,批量删除
    stark组件的增删改(新)
    stark组件的增删改
    stark组件之展示数据(查)
    stark组件配置,二层URL
    单例模式及设计url分发
    Django之modelform
    rbac组件权限按钮,菜单,可拔插
    rbac权限+中间件
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14048765.html
Copyright © 2020-2023  润新知