详解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插件原来如此简单 jQuery插件的机制及实战
Feb 07 Javascript
JS批量操作CSS属性详细解析
Dec 16 Javascript
JavaScript控制table某列不显示的方法
Mar 16 Javascript
JavaScript实现简单的二级导航菜单实例
Apr 15 Javascript
Javascript for in的缺陷总结
Feb 03 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
Jun 29 Javascript
JavaScript之创意时钟项目(实例讲解)
Oct 23 Javascript
不到200行 JavaScript 代码实现富文本编辑器的方法
Jan 03 Javascript
Vue无限滑动周选择日期的组件的示例代码
Jul 18 Javascript
Puppeteer 爬取动态生成的网页实战
Nov 14 Javascript
jQuery基于随机数解决中午吃什么去哪吃问题示例
Dec 29 jQuery
JS实现网页端猜数字小游戏
Mar 06 Javascript
文本溢出插件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
一个SQL管理员的web接口
2006/10/09 PHP
php MsSql server时遇到的中文编码问题
2009/06/11 PHP
linux系统下php安装mbstring扩展的二种方法
2014/01/20 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
Yii2中OAuth扩展及QQ互联登录实现方法
2016/05/16 PHP
php 伪造HTTP_REFERER页面URL来源的三种方法
2016/09/22 PHP
php cookie 详解使用实例
2016/11/03 PHP
禁止F5等快捷键的JS代码
2007/03/06 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
Chrome扩展页面动态绑定JS事件提示错误
2014/02/11 Javascript
我的Node.js学习之路(一)
2014/07/06 Javascript
js格式化时间的方法
2015/12/18 Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
2016/07/05 Javascript
jQuery居中元素scrollleft计算方法示例
2017/01/16 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
jQuery封装animate.css的实例
2018/01/04 jQuery
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
2018/09/25 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
2019/08/17 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
2019/09/06 Javascript
Vue指令实现OutClick的示例
2020/11/16 Javascript
python创建线程示例
2014/05/06 Python
Python+PIL实现支付宝AR红包
2018/02/09 Python
tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法
2018/07/27 Python
python 统计一个列表当中的每一个元素出现了多少次的方法
2018/11/14 Python
Python Opencv实现图像轮廓识别功能
2020/03/23 Python
详解python中的time和datetime的常用方法
2019/07/08 Python
Win10+GPU版Pytorch1.1安装的安装步骤
2019/09/27 Python
Viking Direct爱尔兰:办公用品和家具
2019/11/21 全球购物
学校介绍信范文
2014/01/14 职场文书
高三家长寄语
2014/04/03 职场文书
会计学自荐信
2014/06/03 职场文书
小学生关于梦想的演讲稿
2014/08/22 职场文书
家庭经济困难证明
2015/06/23 职场文书
有关信念的名言语录集锦
2019/12/06 职场文书