Angular 构造函数和ngOnInit之间的区别
Angular默认情况下提供生命周期挂钩Angular 构造函数和ngOnInit之间的区别,angular,typescript,ngoninit,Angular,Typescript,Ngoninit,Angular默认情况下提供生命周期挂钩ngOnInit 如果我们已经有了构造函数,为什么要使用ngOnInit?构造函数是类的默认方法,在实例化类时执行,并确保类及其子类中字段的正确初始化。Angular或更好的依赖注入程序(DI)分析构造函数参数,当它通过调用new MyClass()创建新实例时,它会尝试查找与构造函数参数类型匹配的提供程序,解析它们并将它们传递给构造函数 new MyClass(someArg); ngOnInit是Angular调用的生命周期挂钩,用于指示Angula
ngOnInit
如果我们已经有了
构造函数,为什么要使用ngOnInit
?构造函数是类的默认方法,在实例化类时执行,并确保类及其子类中字段的正确初始化。Angular或更好的依赖注入程序(DI)分析构造函数参数,当它通过调用new MyClass()
创建新实例时,它会尝试查找与构造函数参数类型匹配的提供程序,解析它们并将它们传递给构造函数
new MyClass(someArg);
ngOnInit
是Angular调用的生命周期挂钩,用于指示Angular已完成组件的创建
import {Component} from '@angular/core';
@Component({})
class NGONINITTEST implements onInit{
constructor(){}
//ngOnInit calls by Angular
ngOnInit(){
console.log("Testing ngOnInit");
}
}
为了使用它,我们必须像这样导入OnInit
(实际上实施OnInit
不是强制性的,但被认为是良好的实践):
然后要使用方法OnInit
,我们必须实现如下类:
export class App implements OnInit {
constructor() {
// Called first time before the ngOnInit()
}
ngOnInit() {
// Called after the constructor and called after the first ngOnChanges()
}
}
constructor(private http: Http, private customService: CustomService) {}
实现此接口以在指令的数据绑定属性初始化后执行自定义初始化逻辑。
在第一次检查指令的数据绑定属性之后立即调用ngOnInit,
在检查它的孩子之前。
当指令被实例化时,它只被调用一次
大多数情况下,我们使用ngOnInit
进行所有初始化/声明,避免在构造函数中工作。构造函数应该只用于初始化类成员,而不应该执行实际的“工作”
因此,您应该使用constructor()
来设置依赖项注入,而不是其他。ngOnInit()是一个更好的“起点”——它是解决组件绑定的位置/时间
有关更多信息,请参阅此处:
简短而简单的答案是
构造函数
:
构造函数
是一个默认方法
在构造组件时运行(默认)。当您创建类的实例时,也会调用构造函数(默认方法)
。因此,换句话说,当组件被构造或/或创建实例时,调用构造函数(默认方法)
,并在其中写入相关代码。基本上,通常在Angular2
中,当构建组件以供进一步使用时,它用于注入类似服务的内容
OnInit
:ngOnInit是组件的生命周期挂钩,当组件初始化时,它首先在构造函数(默认方法)
之后运行
因此,将首先调用构造函数,然后在构造函数方法之后调用Oninit
let instance = new NGONINITTEST();
boot.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() {
}
}
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;
}
}
资源:
您可以检查这个,它显示了这两个方面的实现。我认为最好的例子是使用服务。假设我想在组件“激活”时从服务器获取数据。假设在从服务器获取数据后,我还想对数据做一些额外的事情,也许我得到了一个错误,希望以不同的方式记录它
在构造函数上使用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);
};
}
导出类用户实现OnInit{
用户列表:数组;
构造函数(private\u userService:userService){
};
恩戈尼尼特(){
这是getUsers();
};
getUsers(){
this.\u userService.getUsersFromService().subscribe(users=>this.user\u list=users);
};
}
使用我的构造函数,我可以调用我的_userService并填充我的用户列表,但也许我想用它做一些额外的事情。就像确保一切都是大写一样,我不完全确定我的数据是如何通过的
因此,使用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();
};
}
导出类用户实现OnInit{
用户列表:数组;
构造函数(private\u userService:userService){
};
恩戈尼尼特(){
这是getUsers();
};
getUsers(){
this.\u userService.getUsersFromService().subscribe(users=>this.user\u list=users);
this.user_list.toUpperCase();
};
}
这使它更易于查看,因此我在初始化时只调用组件中的函数,而不必在其他地方挖掘它。事实上,这只是另一个工具,你可以使用它使它更容易阅读和使用在未来。此外,我发现将函数调用放在构造函数中是非常糟糕的做法 第一个(构造函数)与类实例化相关,与Angular2无关。我的意思是构造函数可以用于任何类。您可以对新创建的实例进行一些初始化处理
第二个对应于Angular2组件的生命周期挂钩:
引自安格尔官方网站:
- 当输入或输出绑定值更改时,将调用
ngOnChanges
- 在第一个
ngOnChanges
因此,如果初始化处理依赖于组件的绑定(例如,使用@Input
定义的组件参数),则应该使用ngOnInit
,否则构造函数就足够了…来测试这一点,我借用以下代码编写了此代码:
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() {
}
}
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;
}
}
login.component.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() {
}
}
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 ***
上述答案并没有真正回答最初问题的这一方面:什么是生命周期挂钩?我花了一段时间才明白这意味着什么,直到我这样想
1) 假设您的组件是人。人类的生命中有许多恒星
let instance = new NGONINITTEST();
instance.ngOnInit();
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'my-app',
template: `<h1>App is running!</h1>
<my-app-main [data]=data></<my-app-main>`,
styles: ['h1 { font-weight: normal; }']
})
class ExampleComponent implements OnInit {
constructor(private router: Router) {} //Dependency injection in the constructor
// ngOnInit, get called after Component initialised!
ngOnInit() {
console.log('Component initialised!');
}
}
<my-app>
<child-comp [i]='prop'>
MyAppView
- MyApp component instance
- my-app host element data
ChildCompnentView
- ChildComponent component instance
- child-comp host element data
class Some {
constructor() {
this.init();
}
init() {...}
}
constructor(
public foo: Foo,
/* verbose list of dependencies */
) {
// time-sensitive initialization code
this.bar = foo.getBar();
}
ngOnInit() {
// rest of initialization code
}
constructor(
public foo: Foo,
public errorHandler: ErrorHandler
) {}
async ngOnInit() {
try {
await this.foo.getBar();
await this.foo.getBazThatDependsOnBar();
} catch (err) {
this.errorHandler.handleError(err);
}
}
ngOnInit() {
this.someMethod();
super.ngOnInit();
}
constructor(translate: TranslateService, private oauthService: OAuthService) {
translate.setDefaultLang('En');
translate.use('En');}
ngOnInit() {
this.items = [
{ label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
{ label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}
constructor(private
service1: Service1,
service2: Service2
){};
ngOnInit(){
service1.someWork();
};
@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
};