原理圖
直接生成模塊和路由然后定義聲明的模塊
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
計算先前狀態和新對象狀態之間的差異的方法。
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 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
使用了生命周期掛鈎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
比較字典