组件生命周期
(1)组件生命周期钩子
constructor:组件创建时被创建
ngOnChanges: 父组件修改或初始化子组件的输入属性时被调用,如果子组件没有输入属性,则永远不会被调用,它的首次调用发生在ngOnInit之前
ngOnInit:用于初始化组件,因为ngOnChanges事件发生在constructor之后,所以构造函数无法获得输入属性,ngOnInit则能够取到输入属性,所以组件的初始化逻辑一定要依赖输入属性的值,则应该在ngOnInit中初始化而不是构造函数
ngDoCheck:Angular变更检测调用
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
(2)变ngOnChanges
可变对象、不可变对象
在js中,字符串是不可变对象,当一个字符串在内存中被创建后,它的值永远不会被改变。
如上图,第二行代码中的Hello World并不会改变Hello的值,而是重新创建出一个对象,
但是greeting的内存地址由第一个字符串指向了第二个字符串的地址。
而Object是可变对象,在修改Object的属性时,它的内存地址仍一直保持不变。
ngOnChanges钩子只有当输入属性的引用改变时才会被调用
如果输入属性是可变对象,其属性变化不会触发ngOnChanges钩子,但是会触发ngDoCheck钩子
(3)变更检测
变更检测依赖zone.js,用于处理组件属性的改变与模板的同步,浏览器中触发异步事件导致的方法调用会触发变更检测
比如:点击按钮、输入数据、数据从服务器返回,调用setTimeOut方法等等,
一个Angular应用是一个以主组件为根的组件树,每个组件都有其自己的变更检测器,
无论变更发生在哪个组件上,当变更发生时,会从组件树的根往下进行检测,
组件树上的变更检测器都会根据自己的变更检测策略(Default策略、OnPush策略)进行检测
变更检测会调用ngDoCheck钩子、ngAfterContentChecked钩子、ngAfterViewChecked钩子,
所以使用这些钩子时可能会出现性能问题
(4)AfterViewInit、AfterViewChecked
1、ngAfterViewInit、ngAfterViewChecked两个钩子会在视图组装完毕后被先后调用,
子组件会先调用这两个方法,然后父组件调用。ngAfterViewInit只会在视图组装完毕后被调用一次
ngAfterViewChecked会在ngAfterViewInit之后被调用一次,之后每发生变更检测会再被调用
、
2、在子组件中异步调用方法,触发变更检测,会先触发子组件的变更检测、再触发父组件的变更检测
3、在一个变更检测周期中,Angular禁止在一个视图被组装完毕之后再去更新视图,
所以不要在ngAfterViewInit和ngAfterViewChecked中更新视图中绑定的属性
然而ngAfterContentInit和ngAfterContentChecked触发时,组件尚未组装完毕,在这两个方法中可以修改模板中的绑定属性
变更检测是通过异步事件触发的,通过异步事件重新开启一个变更检测周期去改变绑定的属性不会报错
由于ngAfterViewInit只会执行一次,所以可以使用setTimeOut方法更改绑定的属性
但是在ngAfterViewChecked中使用此方法会造成无限循环
(5)运行时动态改变模板的内容又不使用路由,可以通过投影实现
通过在模板子组件标签中填充内容可以将内容投影到子组件中
通过select指定投影的内容
另一种在绑定动态html内容的方式,但是innerHtml只是浏览器中的特性,跨平台性不好
(6)ngAfterContentInit、ngAfterContentChecked
ngAfterContentInit、ngAfterContentChecked是投影相关的钩子
(7)ngOnDestroy
当从一个路由地址跳转到另一个路由地址时,前一个组件会被销毁,后一个组件会被创建
组件被销毁时会调用ngOnDestroy钩子,通常会在组件被销毁时反订阅一个流或者清除定时器等等
,