详解Angular之constructor和ngOnInit差异及适用场景

Angular中根据适用场景定义了很多生命周期函数,其本质上是事件的响应函数,其中最常用的就是ngOnInit。但在TypeScript或ES6中还存在着名为constructor的构造函数,开发过程中经常会混淆二者,毕竟它们的含义有某些重复部分,那ngOnInit和constructor之间有什么区别呢?它们各自的适用场景又是什么呢?

区别

constructor是ES6引入类的概念后新出现的东东,是类的自身属性,并不属于Angular的范畴,所以Angular没有办法控制constructor。constructor会在类生成实例时调用:

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

@Component({
  selector: 'hello-world',
  templateUrl: 'hello-world.html'
})

class HelloWorld {
  constructor() {
    console.log('constructor被调用,但和Angular无关');
  }
}

// 生成类实例,此时会调用constructor
new HelloWorld();

既然Angular无法控制constructor,那么ngOnInit的出现就不足为奇了,毕竟枪把子得握在自己手里才安全。

ngOnInit的作用根据官方的说法:

ngOnInit用于在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。

ngOnInit属于Angular生命周期的一部分,其在第一轮ngOnChanges完成之后调用,并且只调用一次:

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

@Component({
  selector: 'hello-world',
  templateUrl: 'hello-world.html'
})

class HelloWorld implements OnInit {
  constructor() {

  }

  ngOnInit() {
    console.log('ngOnInit被Angular调用');
  }
}

constructor适用场景

即使Angular定义了ngOnInit,constructor也有其用武之地,其主要作用是注入依赖,特别是在TypeScript开发Angular工程时,经常会遇到类似下面的代码:

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

@Component({
  selector: 'hello-world',
  templateUrl: 'hello-world.html'
})
class HelloWorld {
  constructor(private elementRef: ElementRef) {
    // 在类中就可以使用this.elementRef了
  }
}

constructor中注入的依赖,就可以作为类的属性被使用了。

ngOnInit适用场景

ngOnInit纯粹是通知开发者组件/指令已经被初始化完成了,此时组件/指令上的属性绑定操作以及输入操作已经完成,也就是说在ngOnInit函数中我们已经能够操作组件/指令中被传入的数据了:

// hello-world.ts
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'hello-world',
  template: `<p>Hello {{name}}!</p>`
})
class HelloWorld implements OnInit {
  @Input()
  name: string;

  constructor() {
    // constructor中还不能获取到组件/指令中被传入的数据
    console.log(this.name);   // undefined
  }

  ngOnInit() {
    // ngOnInit中已经能够获取到组件/指令中被传入的数据
    console.log(this.name);   // 传入的数据
  }
}

所以我们可以在ngOnInit中做一些初始化操作。

总结

开发中我们经常在ngOnInit做一些初始化的工作,而这些工作尽量要避免在constructor中进行,constructor中应该只进行依赖注入而不是进行真正的业务操作。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Angular 中 ngOnInit 和 constructor 使用场景

    1. constructor constructor应该是ES6中明确使用constructor来表示构造函数的,构造函数使用在class中,用来做初始化操作.当包含constructor的类被实例化时,构造函数将被调用. 来看例子: class AppComponent { public name: string; constructor(name) { console.log('Constructor initialization'); this.name = name; } } let a

  • 详解Angular之constructor和ngOnInit差异及适用场景

    Angular中根据适用场景定义了很多生命周期函数,其本质上是事件的响应函数,其中最常用的就是ngOnInit.但在TypeScript或ES6中还存在着名为constructor的构造函数,开发过程中经常会混淆二者,毕竟它们的含义有某些重复部分,那ngOnInit和constructor之间有什么区别呢?它们各自的适用场景又是什么呢? 区别 constructor是ES6引入类的概念后新出现的东东,是类的自身属性,并不属于Angular的范畴,所以Angular没有办法控制constructo

  • 详解Angular父子组件通讯

    概述 Angular组件间通讯 组件树,1号是根组件AppComponent. 组件之间松耦合,组件之间知道的越少越好. 组件4里面点击按钮,触发组件5的初始化逻辑. 传统做法:在按钮4的点击事件里调用组件5的方法.紧密耦合. Angular:在组件4根本不知道组件5存在的情况下实现. 使用松耦合的方式在组件之间传递数据开发出高重用性的组件. 使用输入输出属性在父子关系的组件之间传递数据. 一.输入输出属性概述 组件设计成黑盒模型,用输入属性声明从外部世界接收什么东西.不需要知道这些东西从哪里来

  • 详解Angular路由动画及高阶动画函数

    一.路由动画 路由动画需要在host元数据中指定触发器.动画注意不要过多,否则适得其反. 内容优先,引导用户去注意到某个内容.动画只是辅助手段. 在router.animate.ts中定义一个进场动画,一个离场动画. 因为进场动画和离场动画用的特别频繁,有一个别名叫:enter和:leave. import { trigger, state, transition, style, animate} from '@angular/animations'; export const slideToR

  • 详解Angular组件之生命周期(二)

    一.view钩子 view钩子有2个,ngAfterViewInit和ngAfterViewChecked钩子. 1.实现ngAfterViewInit和ngAfterViewChecked钩子时注意事项 以父组件调用子组件方法中例子为基础,在父组件中实现ngAfterViewInit和ngAfterViewChecked钩子. 这两个钩子是在组件的模版所有内容组装完成后,组件模版已经呈现给用户看了,之后这两个钩子方法会被调用. @ViewChild('child1') child1:Child

  • 详解Angular组件生命周期(一)

    概述 组件声明周期以及angular的变化发现机制 红色方法只执行一次. 变更检测执行的绿色方法和和组件初始化阶段执行的绿色方法是一个方法. 总共9个方法. 每个钩子都是@angular/core库里定义的接口. import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-life', templateUrl: './life.component.html', styleUrls: ['./life

  • 详解Angular项目中共享模块的实现

    目录 一.共享CommonModule 二.共享MaterialModule 三.共享ConfirmDialog 一.共享CommonModule 创建share Modele:ng g m share import进来所有需要共享的模块都export出去, 暂时只有CommonModule,以后会有一些需要共享的组件. import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'

  • 详解Angular路由之子路由

    目录 一.子路由语法 二.实例 1.新建2个组件修改其内容 2.修改路由配置 3.修改product.component.ts的模版 一.子路由语法 二.实例 在商品详情页面,除了显示商品id信息,还显示了商品描述,和销售员的信息. 通过子路由实现商品描述组件和销售员信息组件展示在商品详情组件内部. 1.新建2个组件修改其内容 ng g component productDesc ng g component sellerInfo 重点是修改销售员信息组件,显示销售员ID. import { C

  • 详解Angular组件数据不能实时更新到视图上的问题

    目录 问题起源 OnPush策略 当前组件或子组件之一触发了事件 总结 问题起源 MainComponent: @Component({ selector: 'main', template: ` <MenuComponent [isReport]="isReport"> </MenuComponent> `, changeDetection:ChangeDetectionStrategy.OnPush }) export class MainComponent

  • 详解Angular结构型指令模块和样式

    一,结构型指令 *是一个语法糖,<a *ngIf="user.login">退出</a>相当于 <ng-template [ngIf]="user.login"> <a>退出</a> </ng-template> 避免了写ng-template. <ng-template [ngIf]="item.reminder"> <mat-icon > alar

  • 详解Angular动态组件

    使用场景 我们先明确下动态组件的使用场景,在代码运行时要动态加载组件,换成普通人话,代码需要根据具体情况(比如用户的操作,向后台请求结果)确定在某些地方加载某些组件,这些组件不是静态的(不是固定的). 官网的举例就是,构建动态广告条,广告组件不断会推出新的,再用只支持静态组件结构的模板显然是不现实的. 再举一个常见的例子,动态弹出框,弹出的组件是不确定的.不断更新的,这里那里弹出个购买框,那那那又需要弹出样式选择框,静态组件结构模板是不能满足群众日渐增长的需求. 怎么实现 然后我们来找个把手,看

随机推荐