Angular4,生命周期钩子的疑问

发布于 2022-09-05 21:46:35 字数 3747 浏览 10 评论 0

目录结构
图片描述

问题如果我在根组件设置变更检测策略是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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只涨不跌 2022-09-12 21:46:35

1.无论Default还是OnPush,生命周期钩子都会全部执行
2.在Default下,state(在例子里就是那个hooks数组)被认为可变的,于是ngAfterViewInitngAfterViewChecked钩子执行后,会触发ngDoCheck,继而重新渲染视图;所以可以看到在ngAfterViewChecked之后,还有一次ngDoCheckngAfterContentChecked
3.在OnPush下,state被认为是immutable的,于是在初始化结束后不会继续去检测hooks的变化,在ngAfterViewChecked后完成视图渲染,再之后的ngAfterViewInitngAfterViewChecked虽然执行了,但由于hooks的变化没有被检测,所以不会被渲染到视图上

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文