angular4组件生命周期

Angular4 组件生命周期

  • 钩子能够在特定的组件生命周期发生时执行所须要的业务逻辑,红框中的方法只会被调用一次,其他会被屡次调用。
  • 用户在组件初始化后看到组件,变动检测阶段会确保组件的属性与页面同步,若是因为路由等操做,组件从dom树上移除,那angular会执行组件的销毁阶段(变动检测中执行的方法与初始化是一个方法)。
  • 建立一个新组件,在生成的组件上已经实现了OnInit接口,每个钩子都是@angular/core这个库里定义的接口,每一个接口都有惟一的钩子方法,方法名是接口名加ng前缀构成。
  • 当一个组件被建立时,它的钩子函数首先被调用而后执行其余方法,构造函数是必定存在的,其它能够根据需求添加。 ## 组件生命周期
  • constructor:构造器函数,用于注入服务。
  • ngOnChanges:当一个父组件修改或初始化一个子组件的输入属性时被调用。
  • ngOnInit:组件初始化,一般会设置一些初始值。
  • ngDoCheck:手动触发更新检查,在每一个angular的变动检测周期中调用。
  • ngAfterContentInit:内容初始化到组件以后。
  • ngAfterContentChecked:内容变动检测以后。
  • ngAfterViewInit:视图初始化以后。
  • ngAfterViewChecked:视图发生变化检测以后,这个能够用来保证用户视图的及时更新。
  • ngOnDestroy:组件注销时的清理工做,一般用于移除事件监听,退订可观察对象等。

变动检测和DoCheck钩子

  • 在angular中,变动检测是由zone.js包来实现的,主要目的是保证组件的属性的变化和页面的变化是同步的,浏览器中发生的任何异步事件都会触发变动检测。
  • 如何理解变动检测
    • 一个angular应用就是以主组件为根的组件树,当angular组件运行时,每个组件都会生成属于它本身的变动检测器,当任何一个变动检测器检测到变化,zone.js就会根据组件的变动检测策略来检查组件,判断组件是否须要更新它的模板。
    • angular实现了两个变动检测策略,default和OnPush,默认状况下都是default,若是全部的组件都是default策略,无论变动发生在那个组件上,zone.js都会检查整个组件树,用OnPush就不会让它检查这个组件及其子组件。
  • 注:ngDocheck方法在页面点击、获取焦点、改变输入等都会被触发,因此调用此方法是要写清楚判断,不然会增长不要的调用。

view钩子

  • ViewChild装饰器
    ViewChild 装饰器用于获取模板视图中的元素或直接调用其组件中的方法,使用ViewChild装饰器能够在父组件中得到一个子组件的引用。

1.在控制器上用TypeScripe代码html

  • 在父组件的.ts文件中
@ViewChild("child1")    //引用子组件
child1:ChildComponent;      //调用子组件对象
  • 在父组件的.html文件中
<app-child #child1></app-child>    //#child1为模块本地变量
  • 子组件的.ts文件中
greeting() {
    console.log("Hello");
}

2.在父组件模板上调用子组件方法git

  • 在父组件的.ts文件中
@ViewChild("child2")    //引用子组件
child2:ChildComponent;      //调用子组件对象
  • 在父组件的.html文件中
<app-child #child2></app-child>    //#child2为模块本地变量
<button (click)="child2.greeting()">点击调用</button>
  • 子组件的.ts文件中
greeting() {
    console.log("Hello");
}

带有After的钩子

ngAfterViewInitngAfterViewChecked

     1. 这两个方法是视图被组装好后触发的。先调用ngAfterViewInit,并且只在初始化完毕调用一次。
     2. 当子组件的初始化和变动完毕后,父组件的才开始调用。
     3. 在父组件中定义一个变量,而后在ngAfterViewInitngAfterViewChecked这两个方法中改变变量的值,将抛出异常,这是由于angular自身规定,在变动检测周期中,禁止在一个视图已经被组装好后再去更新这个视图,而ngAfterViewInitngAfterViewChecked是在视图被组装好后触发的。解决方法:
     把赋值语句写到一个setTimeout()方法中,让它在另外一个JavaScript运行周期中运行。segmentfault

setTimeout(() => {   
      this.message = "Hello";
},0);

ngAfterContentInitngAfterContentChecked浏览器

    与视图组装有关,针对父组件中投影进来的那部份内容。app

投影

  • 利用父组件作通用模板,而后各个子组件嵌套进去,实现本身的功能,例如作一个提示弹框,确认弹框等能够利用这个原理,在angular中有个投影的ng-content能够用在子组件中,父组件直接传递模板到子组件中。
  • 写法
    第一步在子组件中须要被投影的那个组件中,用标记投影的位置。
<div style="border:3px solid red">
  <ng-content></ng-content>
</div>

第二步在父组件中调用子组件后,在子组件标签之间写一段html,这段html就会被投影过去。dom

<app-red-border>
    <p>我应该在红框中</p>
</app-red-border>
  • 若想将两段html内容投影到不一样的框框内,只要给它们设定不一样的class,在中添加相应的select属性。
<div style="border:3px solid red">
  <ng-content select=".red"></ng-content>
</div>
<div style="border:3px solid green">
  <ng-content select=".green"></ng-content>
</div>
<app-red-border>
    <p class="red">我应该在红框中</p>
    <p class="green">我应该在绿框中</p>
</app-red-border>

整体理解

  • 初始化过程
        在前面的截图中,前四个方法在属性初始化阶段,constructor是实例化对象,ngOnChanges初始化输入属性,onOnInit初始化除输入属性以外的其它属性,而后ngDocheck作一次变动检查,这时,组件的全部属性都已被赋值,而后组件开始渲染视图,首先渲染投影进来的内容,渲染好后调用ngAfterContentInit和ngAfterContentChecked,如有子组件,则子组件初始化,组件视图组装完毕后调用ngAfterViewInit和ngAfterViewChecked,组件初始化结束。
  • 说明
    • 页面呈现后,与用户交互,用户点击、输入等会触发变动检测机制,一旦有变化,带有check的方法都会被调用,若是当前变化致使组件的输入属性也改变了,组件的ngOnchanges也会被调用。
    • 当从一个路由地址跳转到另外一个路由地址时,前一个路由地址对应的组件将被销毁(ngOnDestroy),后一个被建立 。

相关学习连接

    1. angular4基础之组件生命周期(含代码) http://blog.csdn.net/fan2252228703/article/details/78116121
    2. angular开发者网站 http://www.ngfans.net/
    3. angular学习资源 http://www.ngfans.net/topic/5/%E9%95%87%E6%A5%BC-angular%E4%BC%98%E8%B4%A8%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90%E6%94%B6%E9%9B%86
    4. RxJS中文网站 http://cn.rx.js.org/
    5. angular4修仙之路 http://www.javashuo.com/article/p-oputypbm-a.html
相关文章
相关标签/搜索