详解Angular组件生命周期(一)(2)

改变子组件的message属性也不引起子组件的onChanges()方法调用。因为message不是输入属性。而ngOnChanges()只有在输入属性变化时候被调用。

三、变更检测机制和DoCheck()钩子

变更检测由zone.js实现的。保证组件的属性变化和页面的变化同步。浏览器中发生的异步事件(点击按钮,输入数据,数据从服务器返回,调用了setTimeout()方法)都会触发变更检测。

变更检测运行时,检测组件模版上的所有绑定关系,如果组件属性被改变,与其绑定的模版相应区域可能需要更新。

注意:变更检测机制只是将组件属性的改变反应到模版上,变更检测机制本身永远不会改变组件属性的值。

两种变更检测策略。

Default 检测到变化,检查整个组件树。

OnPush 只有当输入属性变化时,才去检测该组件及其子组件。

详解Angular组件生命周期(一)

Angular应用是一个以主组件为根的组件树,每个组件都会生成一个变更检测器,任何一个变更检测器检测到变化,zone.js就根据组件的变更检查策略来检测组件(也就是调doCheck()钩子),来判断组件是否需要更新它的模版。

DoCheck检查是从根组件开始往下检查所有的组件树,不管变更发生在哪个组件。

例子:

监控user.name这种可变对象的属性的改变。

在child中加一个oldUsername来存变更前的username,加一个changeDetected属性标志username是否发生变化,默认是false。 noChangeCount计数器默认是0。

import { Component, OnInit, Input, OnChanges, SimpleChanges, DoCheck } from '@angular/core'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'] }) export class ChildComponent implements OnInit, OnChanges, DoCheck { @Input() greeting: string; @Input() user: { name: string }; message: string = "初始化消息"; oldUsername: string; changeDetected: boolean = false; noChangeCount: number = 0; constructor() { } ngOnInit() { } ngOnChanges(changes: SimpleChanges): void { console.log(JSON.stringify(changes, null, 2)); } ngDoCheck() { if (this.user.name !== this.oldUsername) { this.changeDetected = true; console.log("DoCheck: user.name 从 " + this.oldUsername + "变为" + this.user.name); this.oldUsername = this.user.name; } if (this.changeDetected) {//变化来计数器清0 this.noChangeCount = 0; } else {//没变化 this.noChangeCount++; console.log("DoCheck:user.name没变化时ngDoCheck方法已经被调用" + this.noChangeCount + "次") } this.changeDetected = false;//最后不管变没变标志位复位 } }

详解Angular组件生命周期(一)

页面加载完成:user.name没变化时DoCheck方法已经被调用1次。

详解Angular组件生命周期(一)

鼠标点击,不改变任何值,点击触发变更检测机制,所有组件的DoCheck就会被调用。

详解Angular组件生命周期(一)

修改Tom为Tomb,DoCheck捕捉到Tom变为Tomb。

虽然DoCheck()钩子可以检测到user.name什么时候发生变化,但是使用必须小心,ngDoCheck()钩子被非常频繁的调用。每次变更检测周期后发生变化的地方都会调用。

对ngDoCheck()的实现必须非常高效,非常轻量级,否则容易引起性能问题。

同理:所有带Check关键字的钩子方法都要非常小心。 ngDoCheck,ngAfterContentChecked,ngAfterViewChecked.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygzzx.html