Angular默认提供了生命周期钩子ngOnInit。
为什么要使用ngOnInit,如果我们已经有一个构造函数?
Angular默认提供了生命周期钩子ngOnInit。
为什么要使用ngOnInit,如果我们已经有一个构造函数?
当前回答
我将添加一个重要的东西,在上面的解释中被跳过,并解释什么时候你必须使用ngOnInit。
如果你通过ViewChildren, ContentChildren或ElementRef对组件的DOM进行任何操作,你的原生元素在构造函数阶段将不可用。
然而,由于ngOnInit发生在组件被创建和检查(ngOnChanges)被调用之后,你可以在这一点上访问DOM。
export class App implements OnInit, AfterViewInit, AfterContentInit {
@Input() myInput: string;
@ViewChild() myTemplate: TemplateRef<any>;
@ContentChild(ChildComponent) myComponent: ChildComponent;
constructor(private elementRef: ElementRef) {
// this.elementRef.nativeElement is undefined here
// this.myInput is undefined here
// this.myTemplate is undefined here
// this.myComponent is undefine here
}
ngOnInit() {
// this.elementRef.nativeElement can be used from here on
// value of this.myInput is passed from parent scope
// this.myTemplate and this.myComponent are still undefined
}
ngAfterContentInit() {
// this.myComponent now gets projected in and can be accessed
// this.myTemplate is still undefined
}
ngAfterViewInit() {
// this.myTemplate can be used now as well
}
}
其他回答
构造函数()可以接受参数并用于依赖注入,构造函数()用于添加服务对象。
构造函数在ngOnint()之前调用;
ngOnInit()用于用必要的服务函数调用操作组件,通常,ngOnInit()中调用服务,而不是在构造函数中调用服务
简短而简单的回答是,
构造函数:构造函数是在构造组件时(默认情况下)运行的默认方法。当创建类的实例时,也会调用构造函数(默认方法)。换句话说,当构建组件或/和创建实例时,调用构造函数(默认方法)并调用其中编写的相关代码。基本上,在Angular2中,当组件被构造以供进一步使用时,它被用来注入服务之类的东西。
OnInit: ngOnInit是组件的生命周期钩子,当组件初始化时,它首先在构造函数(默认方法)之后运行。
因此,你的构造函数将首先被调用,Oninit将在构造函数方法之后被调用。
boot.ts
import {Cmomponent, OnInit} from 'angular2/core';
import {ExternalService} from '../externalService';
export class app implements OnInit{
constructor(myService:ExternalService)
{
this.myService=myService;
}
ngOnInit(){
// this.myService.someMethod()
}
}
资源:生命周期钩子
你可以查看这个小演示,它展示了这两件事的实现。
我认为最好的例子是使用服务。假设我想在我的组件“激活”时从我的服务器获取数据。假设我还想在从服务器获取数据后对数据做一些额外的处理,也许我得到了一个错误,想要以不同的方式记录它。
在构造函数上使用ngOnInit真的很容易,它还限制了我需要添加到应用程序中的回调层的数量。
例如:
export class Users implements OnInit{
user_list: Array<any>;
constructor(private _userService: UserService){
};
ngOnInit(){
this.getUsers();
};
getUsers(){
this._userService.getUsersFromService().subscribe(users => this.user_list = users);
};
}
对于构造函数,我可以只调用我的_userService并填充我的user_list,但也许我想对它做一些额外的事情。比如确保所有内容都是大写的,我不完全确定我的数据是如何通过的。
这让使用ngOnInit更容易。
export class Users implements OnInit{
user_list: Array<any>;
constructor(private _userService: UserService){
};
ngOnInit(){
this.getUsers();
};
getUsers(){
this._userService.getUsersFromService().subscribe(users => this.user_list = users);
this.user_list.toUpperCase();
};
}
它使它更容易看到,所以当我初始化时,我只是在组件中调用我的函数而不是在其他地方寻找它。实际上,它只是另一个工具,可以让你在将来更容易阅读和使用。此外,我发现将函数调用放在构造函数中是非常糟糕的实践!
该构造函数在Angular“实例化/构造”组件时被调用。 ngOnInit方法是一个钩子,它表示组件生命周期的初始化部分。 一个好的做法是只在服务注入时使用它:
constructor(private
service1: Service1,
service2: Service2
){};
即使有可能,你也不应该在里面做一些“工作”。 如果你想在组件“初始化”时启动一些动作,请使用ngOnInit:
ngOnInit(){
service1.someWork();
};
此外,涉及来自父组件的输入属性的操作不能在构造函数中完成。 它们应该放在ngOnInit方法或其他钩子中。 与视图(DOM)相关的元素也是一样的,例如viewchild元素:
@Input itemFromParent: string;
@ViewChild('childView') childView;
constructor(){
console.log(itemFromParent); // KO
// childView is undefined here
};
ngOnInit(){
console.log(itemFromParent); // OK
// childView is undefined here, you can manipulate here
};
构造函数是类的默认方法,在类实例化时执行,并确保类及其子类中的字段正确初始化。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进行所有的初始化/声明,避免在构造函数中工作。构造函数应该只用于初始化类成员,而不应该做实际的“工作”。
因此,您应该使用构造函数()来设置依赖注入,而不是其他什么。ngOnInit()是更好的“开始”的地方——它是解析组件绑定的地方。
更多信息请参考这里:
https://angular.io/api/core/OnInit Angular组件构造函数Vs OnInit
需要注意的是,@Input值在构造函数中是不可访问的(感谢@tim在注释中提出的建议)