@Directive({selector: '[mySpy]'})export class SpyDirective implements OnInit, OnDestroy { constructor(private logger: LoggerService) { } ngOnInit() { this.logIt(`onInit`); } ngOnDestroy() { this.logIt(`onDestroy`); } private logIt(msg: string) { this.logger.log(`Spy #${nextId++} ${msg}`); }}
我们可以把这个侦探指令写到任何原生元素或组件元素上,它将与所在的组件同时初始化和销毁。
{ {hero}}
ngOnChanges
-- 在ngOnInit之前调用,只后还会调用ngOnChanges()很多次
-- 一旦检测到该组件的@Input属性发生了变化,Angular就会调用它的ngOnChanges()
方法。
ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); }}
Angular不会关注对象属性的变化,因为对象的引用没有发生变化。
ngDoCheck()
-- 对ngOnChanges的拓展,可以检测到ng忽略的变更。
使用ngOnInit
-- 在构造函数之后马上执行复杂的初始化逻辑
-- 在ng设置完输入属性之后,对该组件进行准备
-- 只执行一次
OnDestory()钩子
-- 一些清理逻辑必须在Angular销毁指令之前运行,把它们放在ngOnDestroy()
中
AfterView钩子
-- AfterViewInint()和AfterChecked()钩子,ng在每次创建组件的子视图(组件)后调用它们。
只能通过带装饰器的属性来访问子视图
@ViewChild(ChildViewComponent) viewChild: ChildViewComponent; //访问子组件的属性 let c = this.viewChild.hero.length > 10 ? `That's a long name` : '';
AfterContent钩子
内容投影(感觉像是vue的solt)
下列迹象表明存在着内容投影:
-- 在组件的元素标签中有HTML
-- 组件的模板中出现了<ng-content>
标签
//父组件里套子组件 `` //父模板里需要用到ng-content template: ` -- projected content begins -- -- projected content ends --`
AfterContent钩子和AfterView相似。关键的不同点是子组件的类型不同。
AfterView钩子所关心的是,这些子组件的元素标签会出现在该组件的模板里。
AfterContent钩子所关心的是,这些子组件被Angular投影进该组件中。
下列AfterContent钩子基于子级内容中值的变化而采取相应的行动,这里我们只能通过带
有装饰器的属性来查询到“子级内容”。
该组件的doSomething()
方法立即更新了组件被绑定的comment
属性。 它下一回合。
回忆一下,Angular在每次调用AfterView钩子之前也会同时调用AfterContent。 Angular在完
成当前组件的视图合成之前,就已经完成了被投影内容的合成。 所以我们仍然有机会去修改
那个视图。