脏值检测需要我们知道的
1.单项数据流,从根节点检查到当前页面节点

2.脏值检测时候的声明周期

更新dom以后 脏值检测需要走两次。下面我们配置一个demo演示。
首先配置我们需要的demo
routing里面路径配置
const routes: Routes = [
{
path: 'home',
component: HomeContainerComponent,
},
{
path: 'change-detection',
pathMatch: 'full',
component: ParentComponent
}
];
我们使用change-detection 路径区做脏值检测
需要两个模块component ----- parents child 先看parent.htm结构
<p>{{ title }}parent works!</p>
<app-child [title]="'Hello'"></app-child>
<br />
<button (click)="handleClick()">触发子视图脏值检测</button>
再看child.html结构 脏值检测使用textContent绑定属性 进行测试。
<span [textContent]="title"></span>
<!--
如果不使用绑定,采用直接写 DOM 的形式可以解决脏值检测无限循环的带来的性能问题
<span #timeRef></span>
-->
<span [textContent]="time | date: 'HH:mm:ss:SSS'"></span>
<p>child works!</p>
<button (click)="handleClick()">触发脏值检测</button>
进入页面change-detection 验证脏值检测的流程。打开core.js 搜索function checkandupdateView函数增加断点。 右下加可以关注component 从根节点一直到child节点

child.js中
export class ChildComponent implements OnInit, AfterViewChecked {
_title = 'hi';
@Input()
public get title(): string {
console.log('子组件脏值检测');
return this._title;
}
public set title(v: string) {
this._title = v;
}
}

显示出来结果。
再来,关注这个函数,打断点

可以看到做了旧值和新值得比较,如果相等就放行。也就是说我们不能在 AfterViewChecked中修改title不然回一直死循环切报错。可以看到当前脏值检测console.log输出两遍

例如,我们继续加入这块代码。之前说过脏值检测这块会走两遍。那么我们这时候赋值,改变原有值,就会一直死循环。
ngAfterViewChecked(): void {
// 在此处会抛出异常,不要在 ngAfterViewChecked
// 或者 ngAfterViewInit 中去改变属性值
this.title = 'hello';
}
结果如下:
通过一个demo来理解脏值检测的基本流程,主要是最上方两张图。1.从根节点开始检查。2.更新视图的时候ngAfterViewChecked 还有ngAfterViewInit 会走两次 所以不要在这个时候改变值。
本文探讨Angular脏值检测的基础流程,从根节点检查到当前页面节点,详细讲解了更新DOM后的双次检测。通过一个具体的demo,展示了如何配置路由、组件结构,并利用textContent进行绑定测试。在core.js中关注checkAndUpdateView函数,可以观察到从根节点到子节点的检查过程。在ngAfterViewChecked和ngAfterViewInit中修改值会导致死循环,应当避免在这些生命周期钩子中改变状态。
2366

被折叠的 条评论
为什么被折叠?



