构造函数和ngOnInit之间的区别

本文翻译自:Difference between Constructor and ngOnInit

Angular provides life cycle hook ngOnInit by default. Angular默认提供生命周期挂钩ngOnInit

Why should ngOnInit be used, if we already have a constructor ? 如果我们已经有了constructor ,为什么还要使用ngOnInit呢?


#1楼

参考:https://stackoom.com/question/2Q3mM/构造函数和ngOnInit之间的区别


#2楼

The Constructor is a default method of the class that is executed when the class is instantiated and ensures proper initialization of fields in the class and its subclasses. Constructor是该类的默认方法,该方法在实例化该类时执行,并确保该类及其子类中字段的正确初始化。 Angular or better Dependency Injector (DI) analyzes the constructor parameters and when it creates a new instance by calling new MyClass() it tries to find providers that match the types of the constructor parameters, resolves them and passes them to the constructor like 角度或更佳的依赖注入器(DI)分析构造函数参数,并在通过调用new MyClass()创建新实例时尝试寻找与构造函数参数类型匹配的提供程序,将其解析并将其传递给构造函数,例如

new MyClass(someArg);

ngOnInit is a life cycle hook called by Angular2 to indicate that Angular is done creating the component. ngOnInitngOnInit调用的生命周期挂钩,以指示Angular已完成创建组件。

We have to import OnInit in order to use like this (actually implementing OnInit is not mandatory but considered good practice): 我们必须导入OnInit才能这样使用(实际上,强制实施OnInit不是强制性的,但被认为是好的做法):

import {Component, OnInit} from '@angular/core';

then to use the method of OnInit we have to implement in the class like this. 然后要使用OnInit的方法,我们必须在此类中实现。

export class App implements OnInit{
  constructor(){
     //called first time before the ngOnInit()
  }

  ngOnInit(){
     //called after the constructor and called  after the first ngOnChanges() 
  }
}

Implement this interface to execute custom initialization logic after your directive's data-bound properties have been initialized. 在初始化指令的数据绑定属性之后,实现此接口以执行自定义初始化逻辑。 ngOnInit is called right after the directive's data-bound properties have been checked for the first time, and before any of its children have been checked. ngOnInit在第一次检查指令的数据绑定属性之后以及在检查其子项之前立即调用。 It is invoked only once when the directive is instantiated. 实例化指令后,仅调用一次。

Mostly we use ngOnInit for all the initialization/declaration and avoid stuff to work in the constructor. 通常,我们将ngOnInit用于所有初始化/声明,并避免在构造函数中起作用。 The constructor should only be used to initialize class members but shouldn't do actual "work". 构造函数应仅用于初始化类成员,而不应执行实际的“工作”。

So you should use constructor() to setup Dependency Injection and not much else. 因此,您应该使用constructor()来设置依赖注入,而无需过多设置。 ngOnInit() is better place to "start" - it's where/when components' bindings are resolved. ngOnInit()是“开始”的更好位置-解析组件绑定的位置/位置。

For more information refer here: 有关更多信息,请参见此处:


#3楼

Short and simple answer would be, 简单而简单的答案是,

Constructor : constructor is a default method runs ( by deafult ) when component is being constructed. Constructorconstructor是一个default method运行( 由deafult)被构建组件时。 When you create an instance of a class that time also constructor(default method) would be called. 创建类an instance时,还会调用constructor(default method) So in other words, when component is being constructed or/and an instance is created constructor(default method) is called and relevant code written within is called. 因此,换句话说,在constructed or/and an instance is created constructor(default method)组件constructed or/and an instance is created constructor(default method)将调用constructed or/and an instance is created constructor(default method)并调用其中编写的相关代码。 Basically and generally in Angular2 it used to inject things like services when component is being constructed for the further use. 基本上,通常在Angular2 ,当构造组件以供进一步使用时,它通常用于注入services东西。

OnInit : ngOnInit is component's life cycle hook which runs first after constructor(default method) when component is being initialized. OnInit :ngOnInit是组件的生命周期挂钩,在初始化组件时,它将首先在constructor(default method)之后运行。

So, Your constructor will be called first and Oninit will be called later after constructor method. 因此,将首先调用构造函数,然后在构造函数方法之后调用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() 
   }
}

Resources: LifeCycle hook 资源: LifeCycle挂钩

You can check this small demo which shows implementation of both things. 您可以查看这个小样的演示 ,它演示了两者的实现。


#4楼

I think the best example would be using services. 我认为最好的例子就是使用服务。 Let's say that I want to grab data from my server when my component gets 'Activated'. 假设我要在我的组件被“激活”时从服务器中获取数据。 Let's say that I also want to do some additional things to the data after I get it from the server, maybe I get an error and want to log it differently. 假设我还想在从服务器获取数据后对数据做一些其他事情,也许我遇到错误并希望以不同的方式记录它。

It is really easy with ngOnInit over a constructor, it also limits how many callback layers I need to add to my application. 在构造函数上使用ngOnInit确实很容易,它还限制了我需要添加到应用程序中的回调层数。

For Example: 例如:

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);
    };


}

with my constructor I could just call my _userService and populate my user_list, but maybe I want to do some extra things with it. 使用我的构造函数,我可以只调用_userService并填充user_list,但也许我想用它做一些额外的事情。 Like make sure everything is upper_case, I am not entirely sure how my data is coming through. 就像确保所有内容都是大写一样,我也不完全确定我的数据是如何传递的。

So it makes it much easier to use ngOnInit. 因此,它使使用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();
    };


}

It makes it much easier to see, and so I just call my function within my component when I initialize instead of having to dig for it somewhere else. 它使查看起来更加容易,因此我在初始化时就在组件中调用函数,而不必在其他地方进行挖掘。 Really it's just another tool you can use to make it easier to read and use in the future. 确实,它只是您可以用来使将来更易于阅读和使用的另一种工具。 Also I find it really bad practice to put function calls within a constructor! 另外,我发现将函数调用放在构造函数中实在是一种不好的做法!


#5楼

The first one (constructor) is related to the class instantiation and has nothing to do with Angular2. 第一个(构造函数)与类实例化相关,与Angular2无关。 I mean a constructor can be used on any class. 我的意思是,构造函数可以在任何类上使用。 You can put in it some initialization processing for the newly created instance. 您可以对新创建的实例进行一些初始化处理。

The second one corresponds to a lifecycle hook of Angular2 components: 第二个对应于Angular2组件的生命周期挂钩:

Quoted from official angular's website: 从Angular官方网站引用:

  • ngOnChanges is called when an input or output binding value changes 输入或输出绑定值更改时,将调用ngOnChanges
  • ngOnInit is called after the first ngOnChanges ngOnInit被第一之后调用ngOnChanges

So you should use ngOnInit if initialization processing relies on bindings of the component (for example component parameters defined with @Input ), otherwise the constructor would be enough... 所以,你应该用ngOnInit如果初始化处理依赖于组件(用于定义例如元件参数绑定@Input ),否则的构造就足够了......


#6楼

To test this, I wrote this code, borrowing from the NativeScript Tutorial : 为了测试这一点,我编写了以下代码,借鉴了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 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;
  }

}

Console output 控制台输出

JS: *** User class constructor property ***  
JS: *** User class constructor constructor ***  
JS: *** Login Component Constructor ***  
JS: *** User class constructor ngOnInit ***  
JS: *** Login Component ngOnInit ***  
发布了0 篇原创文章 · 获赞 73 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/w36680130/article/details/105325010