构造函数
是类的默认方法,它在类实例化时执行,并确保类及其子类中字段的正确初始化。Angular或更好的依赖注入器(DI)分析构造函数参数,当它通过调用new MyClass()
创建新实例时,它会尝试找到与构造函数参数类型匹配的提供程序,解析它们并将它们传递给构造函数,如
new MyClass(someArg);
ngoninit
是Angular调用的生命周期钩子,用于指示Angular创建组件的工作已经完成。
我们必须像这样导入oninit
才能使用它(实际上实现oninit
不是强制性的,但被认为是良好的实践):
import { Component, OnInit } from '@angular/core';
然后,为了使用oninit
方法,我们必须这样实现类:
export class App implements OnInit {
constructor() {
// Called first time before the ngOnInit()
}
ngOnInit() {
// Called after the constructor and called after the first ngOnChanges()
}
}
实现此接口以在指令的数据绑定属性初始化后执行自定义初始化逻辑。在第一次检查指令的数据绑定属性之后,以及在检查它的任何子属性之前,立即调用ngOnInit。在实例化指令时只调用一次。
大多数情况下,我们使用ngoninit
进行所有的初始化/声明,避免在构造函数中工作。构造函数应该只用于初始化类成员,而不应该做实际的“工作”。
因此,您应该使用constructor()
来设置依赖项注入,而不是使用其他方法。ngOnInit()是“开始”的更好的地方--它是解析组件绑定的地方/时间。
有关更多信息,请参阅此处:
>
https://angular.io/api/core/oninit
Angular Component构造函数与OnInit
本文从多角度探讨了构造函数与ngOnInit在Angular中的本质区别。这个答案提供了与组件初始化过程相关的最重要的差异解释,也显示了在用法上的不同。
角引导过程包括两个主要阶段:
当Angular构造组件树时调用组件的构造函数。所有生命周期钩子都是作为运行变更检测的一部分调用的。
当Angular构造组件树时,根模块注入器已经配置好,因此您可以注入任何全局依赖关系。此外,当Angular实例化子组件类时,父组件的注入器也已经设置好,因此您可以注入父组件上定义的提供程序,包括父组件本身。组件构造函数是在注入器上下文中调用的唯一方法,因此如果需要任何依赖项,那是获取这些依赖项的唯一地方。
当Angular启动变化检测时,构建组件树,并调用树中所有组件的构造函数。此外,每个组件的模板节点都被添加到DOM中。@input
通信机制是在更改检测期间处理的,因此您不能期望构造函数中有可用的属性。它将在ngoninit
之后提供。
让我们来看一个简单的例子。假设您有以下模板:
<my-app>
<child-comp [i]='prop'>
因此Angular开始引导应用程序。正如我所说的,它首先为每个组件创建类。因此它调用myappcomponent
构造函数。它还创建了一个DOM节点,该节点是my-app
组件的主机元素。然后继续为child-comp
创建一个主机元素,并调用childComponent
构造函数。在这个阶段,它并不真正关心i
输入绑定和任何生命周期挂钩。因此,当这个过程完成时,Angular将以以下组件视图树结束:
MyAppView
- MyApp component instance
- my-app host element data
ChildCompnentView
- ChildComponent component instance
- child-comp host element data
然后才运行my-app
的更改检测和更新绑定,并在MyAppComponent类上调用ngoninit
。然后继续更新child-comp
的绑定,并在ChildComponent类上调用ngoninit
。
根据需要,您可以在构造函数或ngoninit
中执行初始化逻辑。例如,这里的文章是如何在计算@ViewChild查询之前获取ViewContainerRef,展示了需要在构造函数中执行何种类型的初始化逻辑。
以下是一些有助于您更好地理解主题的文章: