zoukankan      html  css  js  c++  java
  • 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 中的所有钩子和调用顺序如下:

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

    2. ngOnInit - 在第一次 ngOnChanges 后调用

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

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

    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();
  • 相关阅读:
    NBUT 1120 Reimu's Teleport (线段树)
    NBUT 1119 Patchouli's Books (STL应用)
    NBUT 1118 Marisa's Affair (排序统计,水)
    NBUT 1117 Kotiya's Incantation(字符输入处理)
    NBUT 1115 Cirno's Trick (水)
    NBUT 1114 Alice's Puppets(排序统计,水)
    188 Best Time to Buy and Sell Stock IV 买卖股票的最佳时机 IV
    187 Repeated DNA Sequences 重复的DNA序列
    179 Largest Number 把数组排成最大的数
    174 Dungeon Game 地下城游戏
  • 原文地址:https://www.cnblogs.com/xuepei/p/7921762.html
Copyright © 2011-2022 走看看