angular4 组件生命周期

红色的被调用一次绿色的会被调用多次,变化检测中的四个方法和组件初始化中的四个方法是一样的。

组件初始化:前面四个初始化属性,后面四个渲染视图

变更检测:使属性值和页面展示保持一致。

组件生命周期顺序:
1.constructor:构造器函数,实例化对象,并用于注入服务
2.ngOnChanges初始化 输入属性,检测到@Input输入数据变化时执行,首次触发发生在ngOnInit前。注意对象的属性发生变化时监听不到
3.ngOnInit初始化 除输入属性之外其他的属性,通常会设置一些初始值(如果初始化的逻辑需要依赖@Input输入属性,那就一定要写在ngOnInit中,而不要写在构造函数中)
4.ngDoCheck组件变更检测时执行
5.ngAfterContentInit投影内容 初始化到组件之后执行
6.ngAfterContentChecked投影内容 变更检测之后执行
7.ngAfterViewInit视图 初始化之后执行
8.ngAfterViewChecked视图 发生变化检测之后执行,这个可以用来保证用户视图的及时更新
9.ngOnDestroy:组件注销时的清理工作,通常用于移除事件监听,退订可观察对象等

 

 

1.onChanges

@input属性(输入属性)发生变化时,会调用;当输入属性为对象时,当对象的属性值发生变化时,不会调用,当对象的引用变化时会触发。

例子:

child.ts代码片段:

@Input()
greeting: string;

@Input()
user:{name:string};

如上,greeting改变会触发ngOnChanges事件,而user.name改变不会触发ngOnChanges事件,因为greeting是字符串是不可变对象(每次值改变的时候都会创建一个新的字符串,然后把引用指向新的字符串),而user是可变对象,修改姓名的值的时候并没有改变user对象的引用。那么怎么监控可变对象呢,用doCheck。

 

2.变更检测机制

angular使用package.json文件中dependencies引入的zone.js来实现变更检测机制。

保证属性的变化和页面的变化是一致的,浏览器中发生的任何变化都会触发变更检测机制,比如点击按钮,输入数据。。。 

Default策略:默认,不管变更发生在哪个组件上,zone都会检测整个组件树

OnPush策略:如果有某个组件声明自身的策略为onPush,只有当这个组件的@input输入属性发生变化时,zone才会检测该组件及其子组件

例子:

  变更检测机制的实现需要实现DoCheck接口中的ngDoCheck()方法。页面上随便一个点击都会触该方法,比如点击输入框等,所有在使用上要非常小心。

import {Component, OnInit,Input,,DoCheck} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements DoCheck{
  constructor() {}

  ngDoCheck():void{
     //组件变更时触发
  }
}

 需要注意的是,当变更检测机制发生的时候,不光是doCheck()方法所有含check关键字的方法(包括ngAfterContentChecked(),ngAfterViewChecked())都会被调用。所以这些方法也都要非常小心的使用。

 

3.view钩子

1.父组件调用子组件的方法

child.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  constructor() { }

  ngOnInit() {}
 //子组件方法
  greeting(name:string){
    console.log("hello"+name);
  }
}

方法一:在模板中通过对子组件标签的模板变量( #变量名)直接调用用子组件方法:

parent.component.html

<!--定义模板变量child1-->
<app-child #child1></app-child>
<app-child #child2></app-child>
<!--在模板中调用子组件greeting()方法-->
<button (click)="child2.greeting('Jerry')"></button>

方法二:在组件类中通过@ViewChild装饰器声明子组件的对象,然后调用子组件对象中的方法

parent.component.ts

import { Component,ViewChild } from '@angular/core';
import {ChildComponent} from "./child/child.component";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  //通过@ViewChild获取的子组件对象
  @ViewChild("child1")
  child1:ChildComponent 

  constructor(){}

  ngOnInit():void{
    this.child1.greeting("Tom");//调用方法
  }
}

2.AfterViewInit和AfterViewChecked

在整个组件模板的内容显示完成,即都已经呈现给用户看之后,会调用这两个方法;

初始化方法AfterViewInit()优先被调用,而且只调用一次AfterViewChecked后调用;

如果存在子组件,则先调用子组件的,再调用父组件的;

 

不要在这两个方法中去改变视图中绑定的东西,如果想改变也要写在一个setTimeout里边,如下:

  例子中,整个视图已经初始化完毕了,又要去修改与视图有绑定的message,会报错,

message:string;

ngAfterViewInit(): void {
    console.log("父组件的视图初始化完毕");
    this.message="Hello";
}

改成:

ngAfterViewInit(): void {
    console.log("父组件的视图初始化完毕");
    setTimeout(()=>{
      this.message="Hello";
    },0);
  }

在javaScript另一个运行周期去运行

 

4.ngContent

ngContent指令用来将父组件模板中的任意html片段投影到子组件中

例子:

child.html

<div>
  <h2>子组件</h2>
  <ng-content select=".header"></ng-content>
  <ng-content select=".footer"></ng-content>
</div>

parent.html

<div>
  <h2>父组件</h2>
  <app-child>
    <div class="header">页头</div>
    <div class="footer">页脚</div>
  </app-child>
</div>

如上,子组件通过<ng-content>指令select属性,分别将父组件的页头和页脚两个div投影到子组件中。

ngAfterContentInitngAfterContentChecked在投影的模板被渲染之后调用。

 

5.ngOnDestroy

从A路由跳到B路由后,A路由对应的组件会执行ngOnDestroy

转载于:https://www.cnblogs.com/Caiyilong/p/8654910.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值