angular 生命周期钩子 ngOnInit() 和 ngAfterViewInit() 的区别
angular 生命周期钩子的详细介绍在 https://angular.cn/guide/lifecycle-hooks 文档中做了介绍。
ngOnInit() 在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件;
ngAfterViewInit() 初始化完组件视图及其子视图之后调用。
ngOnInit() 钩子应该是我们用得最频繁的一个了,在使用命令 ng g component <component-name> 生成一个组件后,就有 ngOnInit() 方法。
ngOnInit() 钩子可以作为初始化时调用一些方法。如:
ngOnInit() 钩子也可以更改视图样式,如:
建议在写 angular 的时候尽量少的使用 jQuery,除非一些简单好用的 jQuery 插件
而 ngAfterViewInit() 钩子是在组件视图或者子组件视图初始化完成之后调用。
项目中遇到了这样一个需求:
一、描述:
1. 通过选择开始时间和结束时间,来查询列表记录:
2. 这个功能在一个模块,4个不同的组件中用到;
3. 初始化时开始时间是当前时间减1天,结束时间是当前时间;
4. 开始时间和结束时间格式“2018-12-03 09:09:09”;
二、解决方法:
1. 时间控件选择了日期时间选择器(Bootstrap日期和时间表单组件);
2. 将日期时间选择器功能进行封装成一个单独的组件 DateTimeSelectorComponent,方便4个组件中用到;
3. 以其中一个父组件 OfflineComponent 为例,监听子组件 DateTimeSelectorComponent 的事件,子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits
(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应;
4. 待子组件返回值了,父组件才做出相应的数据请求和方法调用。这里父组件中就是用 ngAfterViewInit() 钩子。
三、最终结果:
三、实际操作:
1. 首先封装 DateTimeSelectorComponent 组件
- 模板:
<div class="start-end-time-search">
<label for="startTime" class="start-time-label">起止时间</label>
<input type="text" [(ngModel)]="startTime" placeholder="请选择开始时间" readonly id="startTime" class="start-time">
<label for="endTime" class="end-time-label">至</label>
<input type="text" [(ngModel)]="endTime" placeholder="请选择结束时间" readonly id="endTime" class="end-time">
</div>
- 组件
1.暴露一个 EventEmitter 属性,以及定义一些需要返回给父组件的属性
public startTime: string = "";
public endTime: string = "";
public isEnabledSearchBtn: boolean = true; // 查询按钮是可用的
public startTimeErrorTip: string = ""; // 开始时间选择错误提示
public endTimeErrorTip: string = ""; // 结束时间选择错误提示
@Output() timeInfo = new EventEmitter<object>();
2. 定义一个方法来格式化日期时间
// 日期时间格式 "2018-09-20 00:00:00"
dateTimeFormat(dateTime) {
let dateTimeObj = {
"year": dateTime.getFullYear(),
"month": dateTime.getMonth() + 1,
"day": dateTime.getDate(),
"hours": dateTime.getHours(),
"minutes": dateTime.getMinutes(),
"seconds": dateTime.getSeconds()
};
for (let k in dateTimeObj) {
if (dateTimeObj[k] < 10) {
dateTimeObj[k] = "0" + dateTimeObj[k];
}
}
let dateTimeString = dateTimeObj.year + "-" + dateTimeObj.month + "-" + dateTimeObj.day + " "
+ dateTimeObj.hours + ":" + dateTimeObj.minutes + ":" + dateTimeObj.seconds;
return {"obj": dateTimeObj, "string": dateTimeString};
}
返回两种类型,对象类型和字符串类型可供选择。
3. 将信息返回给父组件
// 选择时间,选择完时间或者初始化时,调用一次,将时间信息发送给父组件
selectTime() {
let data = {
isEnabledSearchBtn: this.isEnabledSearchBtn,
startTime: this.startTime,
endTime: this.endTime,
startTimeErrorTip: this.startTimeErrorTip,
endTimeErrorTip: this.endTimeErrorTip
};
this.timeInfo.emit(data);
}
4. 组装数据(返回给父组件的信息)
ngOnInit() {
let initNowTime = this.dateTimeFormat(new Date());
// 开始时间用当前时间减去一天,结束时间使用当前时间
this.startTime = initNowTime.obj.year + "-" + initNowTime.obj.month + "-" +
((initNowTime.obj.day - 1) < 10 ? ("0" + (initNowTime.obj.day - 1)) : (initNowTime.obj.day - 1)) + " " +
initNowTime.obj.hours + ":" + initNowTime.obj.minutes + ":" + initNowTime.obj.seconds; this.endTime = initNowTime.string; this.selectTime(); // 初始化的时候调用一次使得“初始化完组件视图及其子视图之后” startTime 和 endTime 有值 /*下面处理选择的时间*/
let jQuery: any = $;
let that = this;
jQuery("#startTime").datetimepicker({
autoclose: true,
format: "yyyy-mm-dd hh:ii:ss",
minuteStep: 1,
language: "zh-CN",
todayBtn: "linked",
todayHighlight: true,
endDate: (new Date),
zIndexOffset: 1000
}).on("changeDate",function(startTime) {
that.startTime = that.dateTimeFormat(startTime.date).string;
if (Date.parse(that.endTime) - Date.parse(that.startTime) > 31536000000) { // 31536000000 是一年的时间戳
that.startTimeErrorTip = that.endTimeErrorTip == "时间跨度不能大于一年" ? "" : "时间跨度应小于一年";
that.isEnabledSearchBtn = false;
} else if (that.startTime > that.endTime) {
that.startTimeErrorTip = that.endTimeErrorTip == "结束时间不能小于开始时间" ? "" : "开始时间不能大于结束时间";
that.isEnabledSearchBtn = false;
} else {
that.startTimeErrorTip = "";
that.endTimeErrorTip = "";
that.isEnabledSearchBtn = true;
} that.selectTime();
}).data('datetimepicker'); jQuery("#endTime").datetimepicker({
autoclose: true,
format: "yyyy-mm-dd hh:ii:ss",
minuteStep: 1,
language: "zh-CN",
todayBtn: "linked",
todayHighlight: true,
endDate: (new Date),
zIndexOffset: 1000
}).on("changeDate", function(endTime) {
that.endTime = that.dateTimeFormat(endTime.date).string;
if (Date.parse(that.endTime) - Date.parse(that.startTime) > 31536000000) { // 31536000000 是一年的时间戳
that.endTimeErrorTip = that.startTimeErrorTip == "时间跨度应小于一年" ? "" : "时间跨度不能大于一年";
that.isEnabledSearchBtn = false;
} else if (that.startTime > that.endTime) {
that.endTimeErrorTip = that.startTimeErrorTip == "开始时间不能大于结束时间" ? "" : "结束时间不能小于开始时间";
that.isEnabledSearchBtn = false;
} else {
that.startTimeErrorTip = "";
that.endTimeErrorTip = "";
that.isEnabledSearchBtn = true;
} that.selectTime();
}).data('datetimepicker');
}
2. 父组件中使用子组件
- 模板
<app-date-time-selector (timeInfo)="handle($event)"></app-date-time-selector>
父组件绑定的事件属性同子组件中 EventEmitter 属性名称一样
- 组件
// 时间选择器操作事件
handle(value) {
this.startTimeErrorTip = value.startTimeErrorTip;
this.endTimeErrorTip = value.endTimeErrorTip;
this.startTime = value.startTime;
this.endTime = value.endTime;
this.isEnabledSearchBtn = value.isEnabledSearchBtn;
} ngOnInit() { } ngAfterViewInit() {this.offlineRecordList();
}
父组件接收到子组件返回的信息保存在 value 对象中,分别拆分给相应的属性。
最后,当父组件视图和子组件视图完成初始化后,再调用方法,来获取列表数据。
angular 生命周期钩子 ngOnInit() 和 ngAfterViewInit() 的区别的更多相关文章
- Angular 个人深究(四)【生命周期钩子】
Angular 个人深究(四)[生命周期钩子] 定义: 每个组件都有一个被 Angular 管理的生命周期. Angular 创建它,渲染它,创建并渲染它的子组件,在它被绑定的属性发生变化时检查它,并 ...
- Angular 5.x 学习笔记(2) - 生命周期钩子 - 暂时搁浅
Angular 5.x Lifecycle Hooks Learn Note Angular 5.x 生命周期钩子学习笔记 标签(空格分隔): Angular Note on cnblogs.com ...
- Angular组件生命周期——生命周期钩子
生命周期钩子介绍: 1.ngOnChange:响应组件输入值发生变化时触发的事件. 2.ngOnInit:用于数据绑定输入属性之后初始化组件,在第一次ngOnChange之后被调用. a. 组件构造后 ...
- angular生命周期
概述 angular的组件及指令都有相应的声明周期: 创建, 更新, 销毁, 我们可以通过实现相应的生命周期钩子接口来进入相应的该声明周期的关键时刻 组件生命周期顺序 ngOnChanges: 当组件 ...
- Angular4学习笔记(九)- 生命周期钩子简介
简介 Angular 指令的生命周期,它是用来记录指令从创建.应用及销毁的过程.Angular 提供了一系列与指令生命周期相关的钩子,便于我们监控指令生命周期的变化,并执行相关的操作.Angular ...
- Angular2 -- 生命周期钩子
组件生命周期钩子 指令和组件的实例有一个生命周期:新建.更新和销毁. 每个接口都有唯一的一个钩子方法,它们的名字是由接口名加上 ng前缀构成的.比如,OnInit接口的钩子方法叫做ngOnInit. ...
- Angular25 组件的生命周期钩子
1 生命周期钩子概述 组件共有9个生命周期钩子 1.1 生命周期的执行顺序 技巧01:测试时父组件传递对子组件的输入属性进行初始化操作 import { Component, Input, Simpl ...
- angular2的生命周期钩子的使用情况
angular 2 Directive Lifecycleangular2 中组建继承于指令,并扩展了与ui视图相关的属性.angular2 指令的生命周期是用来记录指令从创建,应用及销毁的过程.an ...
- Angular生命周期理解
Angular每个组件,包含根组件和每一级的子组件,都存在一个生命周期,从创建,变更到销毁.Angular提供组件生命周期钩子,把这些关键时刻暴露出来,赋予在这些关键结点和组件进行交互的能力. 在An ...
随机推荐
- JavaScript pop()函数弹出数组最后数据
改变数组中数据的另一种方法是用 .pop() 函数. .pop() 函数用来“抛出”一个数组末尾的值.我们可以把这个“抛出”的值赋给一个变量存储起来. 数组中任何类型的数据条目(数值,字符串,甚至是数 ...
- FileStream文件的使用
// FileStream//(操作字节的)水一勺一勺的 可以操作任意格式的文件 //File一下子就读出来 //读取文本文件 // FileMode.OpenOrCreate你针 ...
- .net core 2.2 部署CentOS7(1)安装虚拟机
目录: .net core 2.2 部署CentOS7(1)安装虚拟机 .net core 2.2 部署CentOS7(2)给虚拟机安装CentOS7 .net core 2.2 部署CentOS7( ...
- [日常] MySQL的哈希索引和原理研究测试
1.哈希索引 :(hash index)基于哈希表实现,只有精确匹配到索引列的查询,才会起到效果.对于每一行数据,存储引擎都会对所有的索引列计算出一个哈希码(hash code),哈希码是一个较小的整 ...
- 手把手教你写一个java的orm(五)
生成sql:where 上一篇里我们实现了生成insert的sql,下面要开始实现update,delete,select的sql语句了.但是这些语句有一个比较麻烦的地方是:它们一般后面都会有wher ...
- leetcode实践:找出两个有序数组的中位数
题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 代码实现 package com. ...
- SSM+Redis+Shiro+Maven框架搭建及集成应用
引文: 本文主要讲述项目框架搭建时的一些简单的使用配置,教你如何快速进行项目框架搭建. 技术: Spring+SpringMVC+Mybatis+Redis+Shiro+Maven ...
- centos7下安装sublime text3并配置环境变量
注意:我解压完把sublime_text全改成了sublime,如果未改就是sublime_text 1.官网下载sublime,保存到指定目录,例如/home 2.解压 tar xjf sublim ...
- (利用DOM)在新打开的页面点击关闭当前浏览器窗口
1.在开发过程中我们前端的用户体验中有时候会要求点击一个按钮,关闭当前浏览器窗口.用html DOM就可做到. 2.注意:本次写法要求在新窗口中关闭. target="_blank" ...
- 重构一段基于原生JavaScript的表格绘制代码
为了在CardSimulate项目中方便的显示技能和效果列表,决定重构以前编写的一段JavaScript代码——att表格绘制库,这段代码的作用是将特定的JavaScript数据对象转化为表格,支持精 ...