为什么子组件在父组件的初始加载时被调用四次?

问题描述

我有一个父组件和一个子组件。我知道更改检测会在HTTP请求,setIntervalsetTimeOut等事件上运行。

但是这里没有这些事件,但是,当我的父组件最初加载时,子组件方法calledChildCompo()调用了四次。

当我没有HTTP请求或任何间隔之类的事件时,为什么更改检测在初始加载时执行四次?

AppComponent(父级)

<app-change-det></app-change-det>

ChangeDetComponent.html(子级)

{{ calledChildCompo() }}

ChangeDetComponent.ts(子级)

@Component({
  selector: 'app-change-det',templateUrl: './change-det.component.html',styleUrls: ['./change-det.component.scss']
})
export class ChangeDetComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  calledChildCompo() {
    console.log('child compo is called');
  }

}

解决方法

看看下面的演示,其中没有子组件或父组件Demo

我所拥有的只是

TS


  ngOnInit() {
    console.log('Init')
  }
  testFunction() {
    console.log('TEST')
  }

HTML

{{ testFunction() }}

如果您查看控制台,您将看到4个带有单词TEST的日志,但只有1个“ init”。它只是一个功能按预期工作,功能会重新评估。

请务必注意,重新评估可能会导致您的应用程序变慢。在html中包含函数是一个坏主意。功能会重新评估是否有细微变化

说明

Angular的摘要周期

您看到的是工作的摘要周期。摘要循环是Angular自动更新魔术的工作原理-这是在输入框中键入内容会自动更新任何涉及其值的内容的原因。

摘要循环运行时,它将有效地重画页面上可能已更改的所有内容。

Angular使用一些技巧来查找“可能已更改的所有内容”,而主要技术是观察者。当您使用ng-ifng-class之类的指令时,以及使用{{ yourBindingHere }}之类的绑定时,会自动创建这些观察程序。

这些东西中的每一个都注册了一个观察者。当Angular的摘要周期运行时,要求每个观察者更新其状态。对于ng-class,它将重新运行绑定到它的函数,以查看是否需要更改。这就是您的控制器功能多次运行的原因,并且每次页面上的任何更改都会再次运行。
来源Controller Function Is Executed Multiple Times