详解Angular 中 ngOnInit 和 constructor 使用场景


Posted in Javascript onJune 22, 2017

1. constructor

constructor应该是ES6中明确使用constructor来表示构造函数的,构造函数使用在class中,用来做初始化操作。当包含constructor的类被实例化时,构造函数将被调用。

来看例子:

class AppComponent {
  public name: string;
  constructor(name) {
    console.log('Constructor initialization');
    this.name = name;
  }
}

let appCmp = new AppComponent('AppCmp');  // 这时候构造函数将被调用。
console.log(appCmp.name);

转成ES5代码如下:

var AppComponent = (function () {
  function AppComponent(name) {
    console.log('Constructor initialization');
    this.name = name;
  }
  return AppComponent;  // 这里直接返回一个实例
}());
var appCmp = new AppComponent('AppCmp');
console.log(appCmp.name);

2. ngOnInit

ngOnInitAngularOnInit钩子的实现。用来初始化组件。

Angular中生命周期钩子的调用顺序如下:

  1. ngOnChanges -- 当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前。
  2. ngOnInit() -- 在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。在第一轮ngOnChanges()完成之后调用,只调用一次。
  3. ngDoCheck -- 自定义的方法,用于检测和处理值的改变。
  4. ngAfterContentInit -- 在组件内容初始化之后调用,只适用于组件
  5. ngAfterContentChecked -- 组件每次检查内容时调用,只适用于组件
  6. ngAfterViewInit -- 组件相应的视图初始化之后调用,只适用于组件
  7. ngAfterViewChecked -- 组件每次检查视图时调用,只适用于组件
  8. ngOnDestroy -- 当Angular每次销毁指令/组件之前调用并清扫。在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。

在Angular销毁指令/组件之前调用。

了解了这些之后我们来看一个例子:

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

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

 constructor() {
  console.log('Constructor initialization');
 }

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

这里输出的是:

Constructor initialization
ngOnInit hook has been called

可以看出,constructor的执行是在先的。

那么既然ngOnchanges是输入属性值变化的时候调用,并且ngOnInit是在ngOnchanges执行完之后才调用,而constructor是在组件就实例化的时候就已经调用了,这也就是说,在constructor中我们是取不到输入属性的值的。
所以还是看例子:

// 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 = 'God eyes';
 }
}
// 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); // this.name=undefined
  }

  ngOnInit() {
    console.log('ChildComponent ngOnInit', this.pname); // this.name=God eyes
  }
}

一目了然。

3. 应用场景

看完的上面的部分可以发现,在constructor中不适合进行任何与组件通信类似的复杂操作,一般在constructor中值进行一些简单的初始化工作:依赖注入,变量初始化等。

那么用到组件间通信的方法我们可以放在ngOnInit中去执行,比如异步请求等:

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

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

 constructor(public elementRef: ElementRef) { // 使用构造注入的方式注入依赖对象
  this.name = 'WXY';          // 执行初始化操作
 }

 ngOnInit() {
  this.gotId = this.activatedRoute.params.subscribe(params => this.articleId = params['id']);
 }
}

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

Javascript 相关文章推荐
JQuery Study Notes 学习笔记(一)
Aug 04 Javascript
jQuery 一个图片切换的插件
Oct 09 Javascript
15款jQuery分布引导插件分享
Feb 04 Javascript
JavaScript记录光标在编辑器中位置的实现方法
Apr 22 Javascript
vue制作加载更多功能的正确打开方式
Oct 12 Javascript
几种响应式文字详解
May 19 Javascript
mpvue小程序循环动画开启暂停的实现方法
May 15 Javascript
Node.js系列之安装配置与基本使用(1)
Aug 30 Javascript
Vue的状态管理vuex使用方法详解
Feb 05 Javascript
JavaScript实现字符串与HTML格式相互转换
Mar 17 Javascript
探索浏览器页面关闭window.close()的使用详解
Aug 21 Javascript
vue-calendar-component 封装多日期选择组件的实例代码
Dec 04 Vue.js
文本溢出插件jquery.dotdotdot.js使用方法详解
Jun 22 #jQuery
详解Vue 2.0封装axios笔记
Jun 22 #Javascript
EasyUI中的dataGrid的行内编辑
Jun 22 #Javascript
Ajax高级笔记 JavaScript高级程序设计笔记
Jun 22 #Javascript
vue 请求后台数据的实例代码
Jun 22 #Javascript
深入理解vue.js中的v-if和v-show
Jun 22 #Javascript
vue如何从接口请求数据
Jun 22 #Javascript
You might like
PHP Cookei记录用户历史浏览信息的代码
2016/02/03 PHP
PHP使用PHPExcel实现批量上传到数据库的方法
2017/06/08 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
JavaScript 打地鼠游戏代码说明
2010/10/12 Javascript
JS限制上传图片大小不使用控件在本地实现
2012/12/19 Javascript
javascript自启动函数的问题探讨
2013/10/05 Javascript
PHP abstract与interface之间的区别
2013/11/11 Javascript
使用jquery实现以post打开新窗口
2014/03/19 Javascript
JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
2016/08/26 Javascript
node.js中 stream使用教程
2016/08/28 Javascript
JavaScript递归操作实例浅析
2016/10/31 Javascript
详解Nodejs基于mongoose模块的增删改查的操作
2016/12/21 NodeJs
BootStrap Datepicker 插件修改为默认中文的实现方法
2017/02/10 Javascript
浅谈在Vue.js中如何实现时间转换指令
2019/01/06 Javascript
vue登录以及权限验证相关的实现
2019/10/25 Javascript
vue.js实现简单购物车功能
2020/05/30 Javascript
详解Vue数据驱动原理
2020/11/17 Javascript
基于python yield机制的异步操作同步化编程模型
2016/03/18 Python
PyTorch上实现卷积神经网络CNN的方法
2018/04/28 Python
Python全局变量与局部变量区别及用法分析
2018/09/03 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
Python数据类型之Set集合实例详解
2019/05/07 Python
Django基础知识 URL路由系统详解
2019/07/18 Python
Python集合基本概念与相关操作实例分析
2019/10/30 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
2019/12/11 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
2020/01/02 Python
openCV提取图像中的矩形区域
2020/07/21 Python
Python自定义sorted排序实现方法详解
2020/09/18 Python
深入解析HTML5使用SVG图像时的viewBox属性用法
2015/09/02 HTML / CSS
草莓网化妆品日本站:Strawberrynet日本
2017/10/20 全球购物
市场部专员岗位职责
2013/11/30 职场文书
公司门卫工作职责
2014/06/28 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
夫妻吵架保证书
2015/05/08 职场文书
2015选调生工作总结
2015/07/24 职场文书
Python 中的Sympy详细使用
2021/08/07 Python