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

 更新时间:2021年05月24日 09:14:25   作者:starof  
Angular本身监督所有Angular组件和指令的生命周期 。为了在开发应用程序时顺利进行,您必须了解结果的生命周期。组件是任何Angular应用程序的主要构建块。因此,必须了解它们才能理解组件生命周期的处理步骤。只有这样才能在应用程序的开发中实现。

一、view钩子

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);
}

二、content钩子

包括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中的依赖注入

    本篇文章主要介绍了深入理解Angular中的依赖注入,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • angular.js实现列表orderby排序的方法

    angular.js实现列表orderby排序的方法

    今天小编就为大家分享一篇angular.js实现列表orderby排序的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • Ionic + Angular.js实现图片轮播的方法示例

    Ionic + Angular.js实现图片轮播的方法示例

    图片轮播在我们日常开发中是再熟悉不过的了,下面这篇文章主要给大家介绍了Ionic + Angular实现图片轮播的方法,文中给出了详细的示例代码供大家参考学习,需要的朋友们下面来一起看看吧。
    2017-05-05
  • 详解Angualr 组件间通信

    详解Angualr 组件间通信

    本篇文章主要介绍了Angualr 组件间通信,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • angular6.0开发教程之如何安装angular6.0框架

    angular6.0开发教程之如何安装angular6.0框架

    这篇文章主要介绍了angular6.0开发教程之如何安装angular6.0框架,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • ng-events类似ionic中Events的angular全局事件

    ng-events类似ionic中Events的angular全局事件

    这篇文章主要介绍了ng-events类似ionic中Events的angular全局事件,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • 浅谈关于angularJs中使用$.ajax的注意点

    浅谈关于angularJs中使用$.ajax的注意点

    本篇文章主要介绍了关于angularJs中使用$.ajax的注意点,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Angular实现的简单定时器功能示例

    Angular实现的简单定时器功能示例

    这篇文章主要介绍了Angular实现的简单定时器功能,结合实例形式分析了AngularJS定时器功能的简单实现与使用技巧,需要的朋友可以参考下
    2017-12-12
  • AngularJS中监视Scope变量以及外部调用Scope方法

    AngularJS中监视Scope变量以及外部调用Scope方法

    在AngularJS中,有时候需要监视Scope中的某个变量,因为变量的改变会影响一些界面元素的显示,接下来通过本文给大家介绍AngularJS中监视Scope变量以及外部调用Scope方法,需要的朋友参考下吧
    2016-01-01
  • Angularjs渲染的 using 指令的星级评分系统示例

    Angularjs渲染的 using 指令的星级评分系统示例

    本篇文章主要介绍了Angularjs渲染的 using 指令的星级评分系统示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11

最新评论