angular11源码探索[DoCheck 生命周期和onChanges区别]
网站
https://blog.thoughtram.io/
https://juristr.com/
https://www.concretepage.com/angular/
https://www.youtube.com/c/MundoAtrevido4U/videos
https://www.concretepage.com/angular/
https://blog.mgechev.com/
https://lifewood.hatenablog.com/
#Frontend
原理图
直接生成模块和路由然后定义声明的模块
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
比较字典
angular11源码探索[DoCheck 生命周期和onChanges区别]的更多相关文章
- Vue2.0源码阅读笔记--生命周期
一.Vue2.0的生命周期 Vue2.0的整个生命周期有八个:分别是 1.beforeCreate,2.created,3.beforeMount,4.mounted,5.beforeUpdate,6 ...
- Laravel源码分析--Laravel生命周期详解
一.XDEBUG调试 这里我们需要用到php的 xdebug 拓展,所以需要小伙伴们自己去装一下,因为我这里用的是docker,所以就简单介绍下在docker中使用xdebug的注意点. 1.在php ...
- Spring源码系列 — Bean生命周期
前言 上篇文章中介绍了Spring容器的扩展点,这个是在Bean的创建过程之前执行的逻辑.承接扩展点之后,就是Spring容器的另一个核心:Bean的生命周期过程.这个生命周期过程大致经历了一下的几个 ...
- 深入源码理解SpringBean生命周期
概述 本文描述下Spring的实例化.初始化.销毁,整个SpringBean生命周期,聊一聊BeanPostProcessor的回调时机.Aware方法的回调时机.初始化方法的回调及其顺序.销毁方法的 ...
- Spring源码 21 Bean生命周期
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- 【源码】spring生命周期
一.spring生命周期 1. 实例化Bean 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用crea ...
- Spring源码之Bean生命周期
https://www.jianshu.com/p/1dec08d290c1 https://www.cnblogs.com/zrtqsk/p/3735273.html 总结 将class文件加载成B ...
- tomcat源码阅读之生命周期(LifeCycle)
一.事件机制流程: 1. 当外部事件源发生事件(比如点击了按钮,数据发生改变更新等)时,事件源将事件封装成事件对象Event: 2. 将事件对象交由对应的事件派发器Dispatcher ...
- Eureka源码探索(一)-客户端服务端的启动和负载均衡
1. Eureka源码探索(一)-客户端服务端的启动和负载均衡 1.1. 服务端 1.1.1. 找起始点 目前唯一知道的,就是启动Eureka服务需要添加注解@EnableEurekaServer,但 ...
随机推荐
- D. Generating Sets 解析(思維)
Codeforce 722 D. Generating Sets 解析(思維) 今天我們來看看CF722D 題目連結 題目 略,請直接看原題 前言 真的是沒想到... @copyright petje ...
- elementui中弹出框不能自动换行的解决方案
我们的需求是将客户给的这串无头脑的数据放进这个弹出框?! 可以看到element提供的弹出框并不提供换行的功能 所以这时候我们应该咋整呢?? 我试过了在这个弹出框中套个盒子给盒子添加宽?然后他自己就折 ...
- OAuth2 快速入门
1 OAuth简述 OAuth 2.0 是一个授权协议,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥有者的资源.应用向资源拥有者请求授权,然后取得令牌(token),并用它来访问资源,并且资 ...
- Spring笔记(6) - Spring的BeanFactoryPostProcessor探究
一.背景 在说BeanFactoryPostProcessor之前,先来说下BeanPostProcessor,在前文Spring笔记(2) - 生命周期/属性赋值/自动装配及部分源码解析中讲解了Be ...
- 敲黑板:InnoDB的Double Write,你必须知道
世界上最快的捷径,就是脚踏实地,本文已收录[架构技术专栏]关注这个喜欢分享的地方. 前序 InnoDB引擎有几个重点特性,为其带来了更好的性能和可靠性: 插入缓冲(Insert Buffer) 两次写 ...
- Redis学习五(Redis 阻塞的原因及其排查方向).
一.慢查询 因为 Redis 是单线程的,大量的慢查询可能会导致 redis-server 阻塞,可以通过 slowlog get n 获取慢日志,查看详情情况. 二.bigkey 大对象 bigke ...
- XJOI NOI训练2 传送
NTT循环卷积 30分: 可以发现这是一个很明显的分层$DP$,设$dp[i][j]$表示当前走了j步走到i号节点的方案数.如果当前走的步数对节点有限制就直接将这个点的$DP$值赋成$0$ #incl ...
- Java_进程与线程
进Process&Thread 区别 进程 线程 根本区别 作为资源分配的单位 调度和执行的单位 开销 每个进程都有独立的代码和数据空间(进程上下文), 进程间的切换会有较大的开销 线程可以看 ...
- mongoDB之C#and.net Driver
之前一直都是用NodeJS来连接操作mongoDB的,但是最近需要用C#操作mongoDB的需要,所以研究了下C#驱动.mongoDB官方在GitHub上提供了C#驱动源码https://github ...
- Martini初步
部分内容来自http://jerkwin.github.io/9999/08/01/Martini%E7%B2%97%E7%B2%92%E5%8C%96%E5%8A%9B%E5%9C%BA%E4%BD ...