Angular默认提供了生命周期钩子ngOnInit。
为什么要使用ngOnInit,如果我们已经有一个构造函数?
Angular默认提供了生命周期钩子ngOnInit。
为什么要使用ngOnInit,如果我们已经有一个构造函数?
当前回答
构造函数在类实例化时执行。它与棱角无关。这是Javascript的特性,Angular无法控制它
ngOnInit是Angular特有的,当Angular用所有输入属性初始化组件时,它会被调用
@Input属性在ngOnInit生命周期钩子下可用。这将帮助你做一些初始化的事情,比如从后端服务器获取数据等显示在视图中
@Input属性在构造函数中显示为未定义
其他回答
为了测试这一点,我从NativeScript教程中借鉴编写了以下代码:
user.ts
export class User {
email: string;
password: string;
lastLogin: Date;
constructor(msg:string) {
this.email = "";
this.password = "";
this.lastLogin = new Date();
console.log("*** User class constructor " + msg + " ***");
}
Login() {
}
}
login.component.ts
import {Component} from "@angular/core";
import {User} from "./../../shared/user/user"
@Component({
selector: "login-component",
templateUrl: "pages/login/login.html",
styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginComponent {
user: User = new User("property"); // ONE
isLoggingIn:boolean;
constructor() {
this.user = new User("constructor"); // TWO
console.log("*** Login Component Constructor ***");
}
ngOnInit() {
this.user = new User("ngOnInit"); // THREE
this.user.Login();
this.isLoggingIn = true;
console.log("*** Login Component ngOnInit ***");
}
submit() {
alert("You’re using: " + this.user.email + " " + this.user.lastLogin);
}
toggleDisplay() {
this.isLoggingIn = !this.isLoggingIn;
}
}
控制台输出
JS: *** User class constructor property ***
JS: *** User class constructor constructor ***
JS: *** Login Component Constructor ***
JS: *** User class constructor ngOnInit ***
JS: *** Login Component ngOnInit ***
第一个(构造函数)与类实例化有关,与Angular2无关。构造函数可以用在任何类上。您可以在其中放入一些新创建实例的初始化处理。
第二个对应于Angular2组件的生命周期钩子:
引用自angular官方网站:
当输入或输出绑定值发生变化时调用ngOnChanges 在第一个ngOnChanges之后调用ngOnInit
所以如果初始化处理依赖于组件的绑定(例如用@Input定义的组件参数),你应该使用ngOnInit,否则构造函数就足够了…
构造函数: ES6类(这里是TypeScript)的构造函数方法是类本身的特性,而不是Angular的特性。当调用构造函数时,它不在Angular的控制范围内,这意味着它不是一个合适的钩子来告诉你Angular何时完成了组件的初始化。JavaScript引擎调用构造函数,而不是直接调用Angular。这就是为什么创建了ngOnInit(和AngularJS中的$onInit)生命周期钩子。记住这一点,有一个使用构造函数的合适场景。这就是我们想要利用依赖注入的时候——本质上是为了将依赖“连接”到组件中。
由于构造函数是由JavaScript引擎初始化的,TypeScript允许我们告诉Angular,我们需要将哪些依赖关系映射到特定的属性上。
ngOnInit只是给我们一个信号,表明Angular已经完成了组件的初始化。
这个阶段包括针对我们可能绑定到组件本身的属性的Change Detection的第一步——比如使用@Input()装饰器。
因此,@Input()属性在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()
}
}
资源:生命周期钩子
你可以查看这个小演示,它展示了这两件事的实现。
构造函数是第一个执行的,当@input data为空时有时会发生这种情况! 所以我们使用构造函数注入服务,ngOnInit在后面发生。 构造函数示例:
constructor(translate: TranslateService, private oauthService: OAuthService) {
translate.setDefaultLang('En');
translate.use('En');}
示例ngOnInit:
ngOnInit() {
this.items = [
{ label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
{ label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}
我认为ngOnInit就像winForm中的InitialComponents()。