[Angular] 查看生命周期方法(ngDoCheck)

首先

继续阅读以下文章。
这次我们来讨论一下 ngDoCheck。

最新消息

2021年1月2日

    記事内で扱ったコードを Angular v11.0.5 で確認しました

工作环境

環境バージョン備考Angular CLIv1.6.3 v11.0.5$ ng --versionAngularv4.4.6 v11.0.5同上TypeScriptv4.0.2同上Node.jsv9.2.1 v12.18.3$ node --versionnpmv5.6.0 v6.14.6$ npm --version
ng version 的结果$ ng version

_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | ‘_ \ / _` | | | | |/ _` | ‘__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/

Angular CLI: 11.0.5
Node: 12.18.3
OS: darwin x64

Angular: 11.0.5
… animations, cli, common, compiler, compiler-cli, core, forms
… platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package Version
———————————————————
@angular-devkit/architect 0.1100.5
@angular-devkit/build-angular 0.1100.5
@angular-devkit/core 11.0.5
@angular-devkit/schematics 11.0.5
@schematics/angular 11.0.5
@schematics/update 0.1100.5
rxjs 6.6.0
typescript 4.0.2

相关文章

    • [Angular] ライフサイクルメソッドをみる(ngOnChanges と ngOnInit と ngOnDestroy)

 

    • [Angular] ライフサイクルメソッドをみる(ngAfterContentInit と ngAfterContentChecked)

 

    [Angular] ライフサイクルメソッドをみる(ngAfterViewInit と ngAfterViewChecked)

ngDoCheck 可以翻译为”进行检查”。

每次运行Change Detection时,ngDoCheck都会执行。
在查看官方的API规范时,作为注意事项。

请注意,指令通常不应同时使用DoCheck和OnChanges来响应同一输入的更改,因为当默认的变更检测器检测到更改时,ngOnChanges将继续被调用。

某个。

通过混合使用 ngOnChanges 和 ngDoCheck 来确认为什么会被说出那样的话。
(在下面只提供了子组件的代码。省略了父组件的代码,因为它与这篇文章相同。)

模板

在组件中,可以通过一个块来显示从父组件传递的值,并且还可以准备一个块来进行子组件自身的输入和输出。

<p>
  親コンポーネントで入力された値は... {{hogeInputValue}}
</p>

<label for="inputText">入力項目(子だけ):</label>
<input id="inputText" name="inputText" type="text" [(ngModel)]="ngDoCheckValue" />
<p>
  子コンポーネントで入力された値は... {{ngDoCheckValue}}
</p>

班级

除了从父组件接收数据的 `ngOnChangesValue` 属性之外,还定义了用于自身输入输出的 `ngDoCheckValue` 属性。

// DoCheck は ngDoCheck を実装するためのインターフェース
import { Component, OnInit, Input, OnChanges, DoCheck, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-hoge-hoge',
  templateUrl: './hoge-hoge.component.html',
  styleUrls: ['./hoge-hoge.component.css']
})
export class HogeHogeComponent implements OnInit, OnChanges, DoCheck {

  /**
   * ngOnChanges の確認のためのプロパティ
   *
   * @type {String}
   * @memberof HogeHogeComponent
   */
  @Input()
  ngOnChangesValue: String = '';

  /**
   * ngDoCheck の確認のためのプロパティ
   *
   * @type {String}
   * @memberof HogeHogeComponent
   */
  ngDoCheckValue: String = 'Initial Value';

  constructor() {
    console.log('[constructor] fired');
  }

  ngOnInit(): void {
    console.log('[ngOnInit] fired');
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log('[ngOnChanges] fired. ngOnChangesValue={' + this.ngOnChangesValue + '}' );
  }

  ngDoCheck(): void {
    console.log('[ngDoCheck] fired. ngDoCheckValue={' + this.ngDoCheckValue + '}' );
  }
}

确认执行结果

运行代码时,在日志中会输出如下内容。

刚刚启动

ngDoCheck-01.png

在输出 ngOnChanges 的日志之后输出 ngOnInit 的日志,然后输出 ngDoCheck 的日志。

ngOnChanges -> ngOnInit -> ngDoCheck の順に実行されている

能够确认这一点。就像原始的生命周期钩子图中所示的那样。
令人在意的是

Angular is running in the development mode. Call enableProdMode() to enable the production mode.

通过红框圈出的日志(这是Angular输出的)是指,在这个日志之后,ngDoCheck的日志再次被输出的地方。由此可知,如果DOM发生了变化,ngDoCheck将会运行。

当单独运行ngDoCheck时,验证其操作。

接下来,我们将确认应用程序在启动并完成画面显示后,执行 ngDoCheck() 操作的行为。
(在此期间,我们使用 F5 键重新加载应用程序进行再次运行)

我执行了以下操作。

    1. 将”change value”复制粘贴到”输入项目(仅限子项)”的表单中去

 

    将焦点从输入表单转移开
ngDoCheck-03.png

從日誌中

    画面起動後に出力されたログの後に、今回の操作によって出力された [ngDoCheck] fired. ngDoCheckValue={change value} だけが出力されていること

我可以理解。
这可以解释为只检测子组件(也就是自身)的更改值,并且仅执行ngDoCheck。
关于ngDoCheck日志的开头显示数字“2”,稍后会详细说明。

确认在运行ngOnChanges时的行为

这次我们尝试在应用程序启动并完成页面显示之后,执行 ngOnChanges 操作时,确认 ngDoCheck 的运作情况。
(在这里,我们也使用 F5 快捷键来进行刷新(重新执行应用程序))

我进行了以下操作。

    1. 将「change value」复制粘贴到「输入项目(由父及子)」的表单中。

 

    将焦点从输入表单转移。
ngDoCheck-02.png

从日志中

    ngOnChanges の後に ngDoCheck が実行されていること

明白了。
所谓的意思是,ngDoCheck函数可以检测并执行ngOnChanges钩子函数中传递的属性(即从父组件传递过来的数据)的变化。
关于ngDoCheck日志开头显示数字”2″的问题,稍后会进行说明。

为什么在 ngDoCheck 的日志开头显示数字.

This number is a counter and it increases every time the same log is outputted.
As for why the same log is being outputted, it is due to the aforementioned operation. (Translation may vary slightly based on contextual understanding)

将焦点从输入表单转移

详细地观察后发现,列出了这一项目。这是导致相同日志输出的原因。

    1. 执行NgOnChange或NgDoCheck操作

 

    1. 在这里更新每个输入值

 

    1. 这样就会触发NgDoCheck,并在日志中输出[ngDoCheck] fired. ngDoCheckValue={change value}

 

    1. 然后将焦点从输入表单移开

 

    1. 可以通过TAB键或鼠标点击进行移动

 

    1. 这样就会触发NgDoCheck

 

    1. 由于输入值没有改变,所以会输出相同的日志([ngDoCheck] fired. ngDoCheckValue={change value})

 

    由于输出的日志相同,数字会递增

而且,即使重新聚焦输入表单,日志也会进行计数(执行ngDoCheck)。

通过动作确认可以了解到的信息。

通过上述的操作确认,我们可以得出以下结论。

    • アプリ起動時の実行順序は Lifecycle Hooks の図面の通り

 

    • ngDoCheck は ngOnChanges がフックしているプロパティの変更も検知して実行される

 

    ngDoCheck は入力フォームからフォーカスが外れたり再フォーカスされても実行される

不应该同时使用 ngOnChanges 和 ngDoCheck 的原因是在开头所写的。

ngDoCheck は ngOnChanges がフックしているプロパティの変更も検知して実行される

在`ngOnChanges`中检测属性的变化并进行处理时,这个变化将会触发`ngDoCheck`的执行,可能会带来额外的性能负担。
此外,`ngOnChanges`可能会引发一些错误,例如在`ngOnChanges`中修改了值,然后在`ngDoCheck`中再次更新它。

除了上述的内容以外

    ngDoCheck は入力フォームからフォーカスが外れたり再フォーカスされても実行される

从这个事实来看,我们可以得出 ngDoCheck 方法会频繁地被执行。

总结起来

我已经确认了ngDoCheck的操作,但由于与ngOnChanges的组合问题以及调用频率等等,我觉得这个方法在使用上很困难。

在本家的DoCheck函数中有以下一句话。

使用此方法来检测Angular忽略的变化。

由于Angular忽略了这种变化,我们首先要从那里开始理解。

我们接下来来看一下生命周期方法。

源代码

以下是本次文章使用的代码的操作确认,请参考…

广告
将在 10 秒后关闭
bannerAds