Angular2 constructor VS ngOnInit

constructor和ngOnInit鉤子有什麼不一樣?app

constructor

constructor(構造函數)是ES6類或TypeScript類中的特殊方法,而不是Angular的方法,主要用來作初始化操做,在進行類實例化操做是,會被自動調用。經過constructor方法並不能使咱們知道Angular什麼時候完成了組件的初始化工做。函數

僅顯示constructor方法:this

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

@Component({})
class ExampleComponent {
  // this is called by the JavaScript engine
  // rather than Angular
  constructor(name) {
    console.log('Constructor initialised');
    this.name = name;
  }
}

// internally calls the constructor
let appCmp = new ExampleComponent('AppCmp');
console.log(appCmp.name);

運行以上代碼,控制檯輸出結果:spa

Constructor initialization
AppCmp

constructor方法是由JavaScript引擎調用的,而不是Angular,這就是爲何ngOnInit生命週期鉤子被建立的緣由。code

ngOnInit

ngOnInit 是 Angular 2 組件生命週期中的一個鉤子,Angular 2 中的全部鉤子和調用順序以下:component

  1. ngOnChanges - 當數據綁定輸入屬性的值發生變化時調用對象

  2. ngOnInit - 在第一次 ngOnChanges 後調用blog

  3. ngDoCheck - 自定義的方法,用於檢測和處理值的改變生命週期

  4. ngAfterContentInit - 在組件內容初始化以後調用ip

  5. ngAfterContentChecked - 組件每次檢查內容時調用

  6. ngAfterViewInit - 組件相應的視圖初始化以後調用

  7. ngAfterViewChecked - 組件每次檢查視圖時調用

  8. ngOnDestroy - 指令銷燬前調用

其中 ngOnInit 用於在 Angular 獲取輸入屬性後初始化組件,該鉤子方法會在第一次 ngOnChanges 以後被調用。

另外須要注意的是 ngOnInit 鉤子只會被調用一次,咱們來看一下具體示例:

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

@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <p>Hello {{name}}</p>
  `,
})
export class AppComponent implements OnInit {

  name: string = '';

  constructor() {
    console.log('Constructor initialization');
    this.name = 'Semlinker';
  }

  ngOnInit() {
    console.log('ngOnInit hook has been called');
  }
}

 

以上代碼運行後,控制檯輸出結果:

Constructor initialization
ngOnInit hook has been called

接下來看一個父-子組件傳參的例子:

parent.component.ts

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

@Component({
  selector: 'exe-parent',
  template: `
    <h1>Welcome to Angular World</h1>
    <p>Hello {{name}}</p>
    <exe-child [pname]="name"></exe-child>
  `,
})
export class ParentComponent {
  name: string = '';

  constructor() {
    this.name = 'Semlinker';
  }
}

child.component.ts

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

@Component({
    selector: 'exe-child',
    template: `
     <p>父組件的名稱:{{pname}} </p>
    `
})
export class ChildComponent implements OnInit {
    @Input()
    pname: string; // 父組件的名稱

    constructor() {
        console.log('ChildComponent constructor', this.pname); // Output:undefined
    }

    ngOnInit() {
        console.log('ChildComponent ngOnInit', this.pname);
    }
}

以上代碼運行後,控制檯輸出結果:

ChildComponent constructor undefined
ChildComponent ngOnInit Semlinker

咱們發如今 ChildComponent 構造函數中,是沒法獲取輸入屬性的值,而在 ngOnInit 方法中,咱們能正常獲取輸入屬性的值。由於 ChildComponent 組件的構造函數會優先執行,當 ChildComponent 組件輸入屬性變化時會自動觸發 ngOnChanges 鉤子,而後在調用 ngOnInit 鉤子方法,因此在 ngOnInit 方法內能獲取到輸入的屬性。

constructor 應用場景

在 Angular 2 中,構造函數通常用於依賴注入或執行一些簡單的初始化操做。

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

@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <p>Hello {{name}}</p>
  `,
})
export class AppComponent {
  name: string = '';

  constructor(public elementRef: ElementRef) { // 使用構造注入的方式注入依賴對象
    this.name = 'Semlinker'; // 執行初始化操做
  }
}

ngOnInit 應用場景

在項目開發中咱們要儘可能保持構造函數簡單明瞭,讓它只執行簡單的數據初始化操做,所以咱們會把其餘的初始化操做放在 ngOnInit 鉤子中去執行。如在組件獲取輸入屬性以後,需執行組件初始化操做等。

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

@Component({})
class ExampleComponent implements OnInit {
  constructor() {}
  
  // called on demand by Angular
  ngOnInit() {
    console.log('ngOnInit fired');
  }
}

const instance = new ExampleComponent();

// Angular calls this when necessary
instance.ngOnInit();
相關文章
相關標籤/搜索