好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Angular2 constructor VS ngOnInit

constructor和ngOnInit钩子有什么不同?

constructor

constructor(构造函数)是ES6类或TypeScript类中的特殊方法,而不是Angular的方法,主要用来做初始化操作,在进行类实例化操作是,会被自动调用。通过constructor方法并不能使我们知道Angular何时完成了组件的初始化工作。

仅显示constructor方法:

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

运行以上代码,控制台输出结果:

 Constructor initialization
AppCmp 

constructor方法是由JavaScript引擎调用的,而不是Angular,这就是为什么ngOnInit生命周期钩子被创建的原因。

ngOnInit

ngOnInit 是 Angular 2 组件生命周期中的一个钩子,Angular 2 中的所有钩子和调用顺序如下:

ngOnChanges - 当数据绑定输入属性的值发生变化时调用

ngOnInit - 在第一次 ngOnChanges 后调用

ngDoCheck - 自定义的方法,用于检测和处理值的改变

ngAfterContentInit - 在组件内容初始化之后调用

ngAfterContentChecked - 组件每次检查内容时调用

ngAfterViewInit - 组件相应的视图初始化之后调用

ngAfterViewChecked - 组件每次检查视图时调用

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

 

查看更多关于Angular2 constructor VS ngOnInit的详细内容...

  阅读:35次