您的位置:首页 > Web前端 > AngularJS

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

2020-11-27 16:23 1381 查看

原理图

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

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
是不同地图差异策略的存储库。角内部使用它的指令
NgClass
NgStyle
等等。无论何时,只要结合这些指令值的变化,这些变化体现。为了处理和更新更改,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
计算先前状态和新对象状态 56c 之间的差异的方法。

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

5.

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

6.

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

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

完整的例子

export class UserCo
56c
mponent 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
使用了生命周期挂钩
ngOnChanges
ngDoCheck
ngOnChanges
该指令用于使用集合
find
实例的方法根据当前集合的类型选择一个差异
IterableDiffers
ngDoCheck
用于将差值应用于集合的当前值。在不同的是要收集与以前的值进行比较,并返回更改列表

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

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
比较字典

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: