angular封装公共组件(详解Angular组件之生命周期二)
angular封装公共组件
详解Angular组件之生命周期二目录
- 一、view钩子
- 1、实现ngAfterViewInit和ngAfterViewChecked钩子时注意事项
- 2、在一个变更检测周期中禁止一个视图被组装好之后再去更新视图
- 二、content钩子
- 1、Content钩子的调用顺序例子
- 2、Content钩子中可以修改模版内容
- 三、总结
view钩子有2个,ngAfterViewInit和ngAfterViewChecked钩子。
1、实现ngAfterViewInit和ngAfterViewChecked钩子时注意事项
以父组件调用子组件方法中例子为基础,在父组件中实现ngAfterViewInit和ngAfterViewChecked钩子。
这两个钩子是在组件的模版所有内容组装完成后,组件模版已经呈现给用户看了,之后这两个钩子方法会被调用。
@ViewChild('child1') child1:Child1Component; //父组件中获得子组件的引用 ngOnInit(){ this.child1.greeting("Tom"); } ngAfterViewInit(){ console.log("父组件的视图初始化完毕"); } ngAfterViewChecked(){ console.log("父组件的视图变更检测完毕"); }
在子组件中也实现这两个钩子
export class Child1Component implements OnInit,AfterViewInit,AfterViewChecked{ constructor() { } ngOnInit() { } greeting(name: string) { console.log("hello" + name); } ngAfterViewInit(){ console.log("子组件的视图初始化完毕"); } ngAfterViewChecked(){ console.log("子组件的视图变更检测完毕"); } }
在父组件的ngOnInit中不直接调用子组件的greeting()方法,而是通过一个定时器每隔5s去调用一次。
ngOnInit(){ setInterval(()=>{ this.child1.greeting("Tom"); },5000); }
总结:
1、Init先调用,checked后调用
看1中,首先子组件视图初始化完毕,然后子组件视图变更检测完毕。
2、子组件先于父组件被组装好
看2中,因为父组件中声明了2个子组件,所以看到有2个子组件 初始化的动作。1号子组件初始化完毕,变更检测完毕,2号子组件初始化完毕,变更检测完毕后,父组件的初始化完毕才会被调用,然后父组件的变更检测完毕才会被调用。
3、ngAfterViewInit只会在初始化完毕被调用一次。
4、定时器触发方法后,两个子组件的变更检测会被调用,父组件的变更检测也会被调用。
视图没有发生任何改变,变更检测也会被调用,实现来ngAfterViewChecked()钩子的方法都会被调用。
所以ngAfterViewChecked()钩子一定要写的精简以免出现性能问题。
2、在一个变更检测周期中禁止一个视图被组装好之后再去更新视图
例子:
父组件
有一个message初始化为abc.显示到模版上。
message:string='abc';
在父组件的ngAfterViewInit中更改message值。
ngAfterViewInit(){ console.log("父组件的视图初始化完毕"); this.message="def"; }
会报错。ngAfterViewInit()和ngAfterViewChecked()都是在视图组装完成后触发的,所以在这两个钩子中更新组件中被绑定的属性,触发组件视图的变化,Angular就会抛出异常。
解决办法:
把代码放在另一个时间循环里面。
ngAfterViewInit(){ console.log("父组件的视图初始化完毕"); setTimeout(()=>{ this.message="def"; },0); }
包括2个与投影相关的钩子,ngAfterContentInit()和ngAfterContentChecked()钩子。
ngAfterContentInit,ngAfterContentChecked和ngAfterViewInit,ngAfterViewChecked类似。
ngAfterViewInit,ngAfteViewChecked是在整个组件的视图全部组装完成后调用的。
ngAfterContentInit,ngAfterContentChecked是在被投影进来的内容组装完成后调用的。
1、Content钩子的调用顺序例子
父组件中实现ngAfterContentInit,ngAfterContentChecked和ngAfterContentInit()
export class AppComponent implements OnInit, AfterViewInit, AfterContentInit,AfterContentChecked{ ngAfterViewInit(){ console.log("父组件的视图初始化完毕"); } ngAfterContentInit(){ console.log("父组件投影内容初始化完毕"); } ngAfterContentChecked(){ console.log("父组件投影内容变更检测完毕"); }
子组件中也实现这3个接口
export class Child2Component implements OnInit,AfterViewChecked,AfterContentInit,AfterContentChecked{ constructor() { } ngOnInit() { } ngAfterViewInit(){ console.log("子组件的视图初始化完毕"); } ngAfterContentInit(){ console.log("子组件投影内容初始化完毕"); } ngAfterContentChecked(){ console.log("子组件投影内容变更检测完毕"); } }
组装视图时,先组装投影进来的内容,然后组装子组件中视图的内容,再加上父组件本身的内容,然后才是父组件视图初始化完毕。
2、Content钩子中可以修改模版内容
view钩子里不能修改模版内容,因为模版内容组装完毕后不能再修改里面内容。但是Content钩子里可以。
因为Content钩子调用时整个视图还没有组装完毕,只是投影进来的内容被组装完毕了。
父组件中在ngAfterContentInit钩子里修改message信息不会报错。
export class AppComponent implements OnInit, AfterViewInit, AfterContentInit,AfterContentChecked{ message:string='abc'; ngAfterViewInit(){ console.log("父组件的视图初始化完毕"); } ngAfterContentInit(){ console.log("父组件投影内容初始化完毕"); this.message='def'; } ngAfterContentChecked(){ console.log("父组件投影内容变更检测完毕"); } ngOnInit(){ }
上面四个方法在属性初始化阶段:构造函数是初始化对象,ngOnChanges是初始化输入属性,ngOnInit是初始化除了输入属性以外其它的所有属性,ngDoCheck是做一次变更检查。
这四个方法执行完整个组件所有属性都被赋予了应该被赋的值。
组件开始渲染它的视图,首先渲染投影进来的内容,投影进来的内容渲染完调用ngAfterContentInit和ngAfterContentChecked钩子方法。
如果有子组件会调子组件创建的过程,子组件创建完或者没有子组件,整个组件的视图都初始化完毕了以后,会调ngAfterViewInit和ngAfterViewChecked钩子方法。
至此,整个组件初始化完毕,组件会呈现给用户交互。
用户交互触发Angular的变更检测机制,检测到发生了变更,在当前组件树上所有活动组件上被实现的带有check的钩子方法都会被调用,用来检查当前组件的变化,如果变化导致某个组件的输入属性也改变了,那个组件的ngOnChanges也会被调用。
组件在路由地址变化从而被销毁的时候会调ngOnDestory()。
在ngOnDestory中销毁一些引用的资源,比如反订阅一个流,清除定时器之类的。
以上就是详解Angular组件之生命周期(二)的详细内容,更多关于Angular的资料请关注开心学习网其它相关文章!
- angular定义一个管道(Angular管道PIPE的介绍与使用方法)
- angular封装进度条组件(如何用DevUI搭建自己的Angular组件库)
- angular开发详解(详解Angular组件生命周期一)
- angular兄弟组件调用方法(Angular封装WangEditor富文本组件的方法)
- angular怎么创建声明(使用Angular CDK实现一个Service弹出Toast组件功能)
- angular简单介绍(详解Angular依赖注入)
- angular快速创建模块指令(详解Angular项目中共享模块的实现)
- angular引入组件库(详解Angular组件之中间人模式)
- angular模块的组成(详解Angular结构型指令模块和样式)
- angular开发详解(详解Angular动态组件)
- angularjs使用指令(详解Angular路由动画及高阶动画函数)
- angularjs数据绑定类指令及作用(详解Angular数据绑定及其实现方式)
- angular组件化(详解Angular父子组件通讯)
- angular使用方法(Angular环境搭建及简单体验小结)
- angular封装公共组件(详解Angular组件之生命周期二)
- angular教程第九讲(浅谈Angular的12个经典问题)
- 魔兽世界 设计师爆料,原始版本并无PVP,跨阵营属于返璞归真(魔兽世界设计师爆料)
- 吐槽完《弧光大作战》之后,我们和设计师聊了聊魔兽首款手游的立项初衷和未来(吐槽完弧光大作战之后)
- 魔兽争霸3自定义战役少年杰雷 2(魔兽争霸3自定义战役少年杰雷)
- 今日菜价 芥兰涨幅最高 1.33 ,花菜降幅最高 3.10(今日菜价芥兰涨幅最高)
- 今日菜价 椰菜涨幅最高 3.25 ,水空心菜降幅最高 2.58(今日菜价椰菜涨幅最高)
- 今日菜价 红三鱼涨幅最高 4.41 ,黄鳝降幅最高 5.06(红三鱼涨幅最高)
热门推荐
- python如何编写一个用户登录系统(Python实现的登录验证系统完整案例基于搭建的MVC框架)
- cdn上传加速(云服务器搭建网站需要用CDN加速吗?)
- hive分析后如何录入mysql(hive从mysql导入数据量变多的解决方案)
- typescript获取属性名(TypeScript 中如何限制对象键名的取值范围)
- laravel队列大批量数据(laravel 中某一字段自增、自减的例子)
- apache 配置域名(apache 二级域名解析 window与linux)
- 百度地图获取api过程(JavaScript接入百度地图API的方法步骤)
- python 文本分析 摘要(用Python逐行分析文件方法)
- dedecms分页效果(织梦dedecms将列表页重复的第一页去除的方法)
- mysql中length、char_length区别