首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UseCases for ngDoCheck (Angular9)

UseCases for ngDoCheck (Angular9)
EN

Stack Overflow用户
提问于 2020-04-02 09:55:47
回答 2查看 731关注 0票数 1

我是一个角度学习的初学者&我自己学习,并且我已经加入了ngDoCheck生命周期方法

根据文档: 对角不能或不愿单独检测的变化进行检测和行动。

父组件:

代码语言:javascript
复制
user={
   name:"xxx"
}

update(){
  this.user.name="yyy"
}

父视图:

代码语言:javascript
复制
<button (click)="update">update</button>
<child-comp [inputprop]="user"></child-comp>

子组件

代码语言:javascript
复制
ngDoCheck(){
console.log(this.inputprop);
}

据我所知,使用这个生命周期方法来获得在更深层次的中的最新变化,ngOnChanges无法在更深层次上检测到输入属性的变化。

简单地说,ngOnChanges只会检测到属性的变化,只对属性的引用进行更改。

上面示例中的生命周期方法没有做任何事情来获得属性的最新变化。但是相反,更改检测有助于获得更深层次的中的最新变化。

我想知道使用ngDoCheck生命周期方法的确切用例。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-02 10:38:23

您的子组件更改检测器可能有以下策略

  1. 默认设置
  2. onPush

在默认策略中,CD将运行@ the ()修饰属性中的任何更改。

在onPush策略中,当您将一个新对象(引用)传递给@Input修饰属性时,CD就会运行。

无论策略如何,CD总是在以下情况下运行,

  1. 像单击、提交之类的事件会被触发。
  2. 使用API的XHR调用
  3. 执行异步JavaScript函数,如assetTimeOut()或setInterval()

请记住,可以将角CD可视化为有向树,这意味着所有组件都可以看作树中的节点,而角总是从根节点运行到树的底部。

即使有一个事件在CC-121中激发,角将运行CD从根组件到底部。但是,CD的运行将停止在将策略设置为onPush的节点上,并且您不会在@Input修饰属性中传递一个新对象。

现在您了解了CD何时以及如何运行,每次CD为组件运行时,都会执行ngDoCheck()生命周期。

希望能帮上忙。

谢谢

票数 2
EN

Stack Overflow用户

发布于 2022-09-29 16:27:25

我看到你被两个生命周期挂钩搞混了。

在角度上,我们可以使用两个不同的生命周期挂钩执行更改检测:

ngOnchanges生命周期挂钩ngDoCheck生命周期挂钩

但在某些情况下,ngOnChanges不足以检测所有更改,因为它使用属性引用来检查差异,因此如果更新对象属性,它就无法检测更改。

同时,ngDoCheck生命周期挂钩允许我们执行自定义更改检测,这样我们就可以绕过ngOnChange生命周期挂钩限制。

例如,如果从父组件传递用户对象,则更新用户对象的年龄或用户名属性,在这种情况下,角将不会触发事件来分派ngOnChange回调。因为它具有与User对象相同的引用。

因此,您可以使用ngDoCheck生命周期挂钩来解决这个问题。

通过使用ngDoCheck,我们可以使用更高级的工具,比如键值不同的迭代不同的服务来执行自定义更改检测。

请查看这个小示例:

代码语言:javascript
复制
  //child-component.ts
import {Component, DoCheck, Input, KeyValueDiffers, OnInit} from "@angular/core";

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
})
export class ChildComponent implements OnInit, DoCheck {

  @Input() user: any;

  changelogList: Array<string> = [];

  differ: any;

  constructor(private differs: KeyValueDiffers) {
  }

  ngOnInit() {
    this.differ = this.differs.find(this.user).create();
  }


  ngDoCheck() {
    const userChanges = this.differ.diff(this.user);
    if (userChanges) {
      userChanges.forEachChangedItem((changeRecord: any) => {
        this.changelogList.push('item changed : ' + changeRecord.key + ' ' + JSON.stringify(changeRecord.currentValue))
      });
      userChanges.forEachAddedItem((changeRecord: any) => {
        this.changelogList.push('item added : ' + changeRecord.key + ' ' + JSON.stringify(changeRecord.currentValue))
      });
    }
  }
}

ngDoCheck中的differ方法返回un对象,该对象提供多个高级方法,例如

forEachItemforEachPreviousItemforEachChangedItemforEachAddedItemforEachRemovedItem.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60988861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档