Angular4,生命周期钩子的疑问
目录结构
问题如果我在根组件设置变更检测策略是OnPush之后,我在根组件下创建了Test组件,并且在Test组件中尝试实现所有的生命周期钩子,但是我发现,在Test组件中钩子函数只会执行到ngContentChecked(),之后的ngAfterViewInit,ngAfterViewChecked并不会执行
代码如下:
app.component.ts
import { Component,
OnInit,
OnChanges,
DoCheck,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
ChangeDetectionStrategy} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
public title: string = 'app';
}
test.component.ts (我尝试实现所有的钩子)
import { Component,
OnInit,
OnChanges,
DoCheck,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
changeDetection: ChangeDetectionStrategy.Default
})
export class TestComponent {
constructor() { }
public hooks: Array<string> = []
ngOnChanges () {
this.hooks.push('ngOnChanges')
}
ngOnInit () {
this.hooks.push('ngOnInit')
}
ngDoCheck () {
this.hooks.push('ngDoCheck')
}
ngAfterContentInit () {
this.hooks.push('ngAfterContentInit')
}
ngAfterContentChecked () {
this.hooks.push('ngAfterContentChecked')
}
ngAfterViewInit () {
this.hooks.push('ngAfterViewInit')
}
ngAfterViewChecked () {
this.hooks.push('ngAfterViewChecked')
}
}
test.component.html
<p>test</p>
<span *ngFor="let item of hooks" >{{item}}, </span>
运行结果如下:
如果,我在根组件的变更检测策略更改为默认的Default后
运行结果如下:
我很想知道为什么???
----------------- 我是可爱的分割符 ------------------
我在app.component.ts使用默认的策略,在test.component.ts使用OnPush策略,结果依然是test钩子函数只会执行到ngContentChecked(),之后的ngAfterViewInit,ngAfterViewChecked并不会执行
test.component.ts(本组件使用OnPush策略)
import { Component,
OnInit,
OnChanges,
DoCheck,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TestComponent {
constructor() { }
public hooks: Array<string> = []
ngOnChanges () {
this.hooks.push('ngOnChanges')
}
ngOnInit () {
this.hooks.push('ngOnInit')
}
ngDoCheck () {
this.hooks.push('ngDoCheck')
}
ngAfterContentInit () {
this.hooks.push('ngAfterContentInit')
}
ngAfterContentChecked () {
this.hooks.push('ngAfterContentChecked')
}
ngAfterViewInit () {
this.hooks.push('ngAfterViewInit')
}
ngAfterViewChecked () {
this.hooks.push('ngAfterViewChecked')
}
}
运行结果如下:
但是改为Default后钩子就会全部正常执行
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1.无论Default还是OnPush,生命周期钩子都会全部执行
2.在Default下,state(在例子里就是那个hooks数组)被认为可变的,于是
ngAfterViewInit
和ngAfterViewChecked
钩子执行后,会触发ngDoCheck
,继而重新渲染视图;所以可以看到在ngAfterViewChecked
之后,还有一次ngDoCheck
和ngAfterContentChecked
3.在OnPush下,state被认为是immutable的,于是在初始化结束后不会继续去检测hooks的变化,在
ngAfterViewChecked
后完成视图渲染,再之后的ngAfterViewInit
和ngAfterViewChecked
虽然执行了,但由于hooks的变化没有被检测,所以不会被渲染到视图上