Angular默认提供了生命周期钩子ngOnInit。

为什么要使用ngOnInit,如果我们已经有一个构造函数?


当前回答

构造函数是在构建组件(或其他类)时执行的函数。

ngOnInit是一个属于组件生命周期方法组的函数,它们在组件的不同时刻执行(这就是为什么命名为life-cycle)。以下是它们的列表:

构造函数将在任何生命周期函数之前执行。

其他回答

构造函数是Typescript类提供的默认方法,专门用于初始化类成员,通常用于依赖注入服务,如上面的示例代码,或定时器初始化,套接字连接初始化

export class AppComponent {
  title = 'angular-fork-join';
  constructor(private http: HttpClient) {}

ngOnInit:是Angular提供的一个生命周期钩子,在组件初始化时调用,专门用于业务逻辑、数据初始化、API调用等。,演示API调用的示例代码:

export class HomeComponent implements OnInit {

  products = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {

    this.dataService.sendGetRequest().subscribe((data: any[])=>{
      console.log(data);
      this.products = data;
    })  
  }

} 

构造函数是类的默认方法,在类实例化时执行,并确保类及其子类中的字段正确初始化。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在注释中提出的建议)

为了测试这一点,我从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 ***  

构造函数在类实例化时执行。它与棱角无关。这是Javascript的特性,Angular无法控制它

ngOnInit是Angular特有的,当Angular用所有输入属性初始化组件时,它会被调用

@Input属性在ngOnInit生命周期钩子下可用。这将帮助你做一些初始化的事情,比如从后端服务器获取数据等显示在视图中

@Input属性在构造函数中显示为未定义

constructor()是Component生命周期中的默认方法,用于依赖注入。构造函数是一个Typescript特性。

ngOnInit()在构造函数之后被调用,ngOnInit在第一个ngOnChanges之后被调用。

例如:

建设者()-> ngOnChanges() -> ngOnInit()

如上所述,当输入或输出绑定值发生变化时调用ngOnChanges()。