組件基礎
組件用來包裝特定的功能,應用程序的有序運行依賴于組件之間的協(xié)同工作。
組件是angular應用的最小邏輯單元,模塊則是在組件之上的一層抽象。所有angular組件都可以獨立存在,也意味著任何組件都可以作為根組件被引導,也可以被路由加載,或在其他組件中使用。不過一個組件不能單獨被啟動,它必須被包裝到模塊里,然后通過Bootstrap
模塊接口引導入口模塊來啟動angular應用。
創(chuàng)建組件的步驟
創(chuàng)建angular組件三步驟:
- 從
@angular/core
中引入Component
裝飾器 - 建立一個普通的類,并用
@Component
修飾它 - 在
@Component
中,設置selector
自定義標簽和template
模板
//contactItem.component.ts
import { Component } from '@angular/core';
@Component({
selector:'contact-item',
template:`
<div>
<p>張三</p>
<p>13800000</p>
</div>
`
})
export class ContactItemComponent {}
以上代碼創(chuàng)建了一個最簡單的組件。使用這個組件需要在HTML中添加<contact-item>
自定義標簽,然后angular便會在此標簽中插入ContactItemComponent
組件中指定的模板。
<div>
<contact-item></contact-item>
</div>
最終會被渲染成:
<div>
<contact-item>
<div>
<p>張三</p>
<p>13800000</p>
</div>
</contact-item>
</div>
組件基礎構成
組件裝飾器
@Component
是TypeScript的語法,它是一個裝飾器,任何一個angular的組件類都會用這個裝飾器修飾,如果移除了這個裝飾器,它將不再是angular的組件。
組件元數(shù)據(jù)
在ContactItemComponent
這個組件中的@Component
裝飾器部分,使用到了大部分組件需要的元數(shù)據(jù):用于定義組件標簽名的selector
;用于定義組件宿主元素模板的template
。
1.selector
selector
是用于定義組件在HTML代碼中匹配的標簽,它將成為組件的命名標記。通常情況下都需要設置selector
,特殊情況下也可以忽略,不指定時默認為匹配div
元素,但不建議這樣做。selector
的命名方式建議用“烤肉串式”命名,即采用小寫字母并以“-”分隔。
2.template
template
是為組件指定一個內聯(lián)模板。使用ES6的多行字符串``語法能夠創(chuàng)建多行模板。
3.templateUrl
templateUrl
是為組件指定一個外部模板的URL地址。
@Component({
templateUrl:'app/component/contact-item.html'
})
每個組件只能指定一個模板,可以使用template
或templateUrl
的引入方式。
4.styles
styles
是為組件指定內聯(lián)樣式。
@Component({
styles:[
`
li:last-child{
border-bottom:none;
}
`
]
})
5.styleUrls
styleUrls
是為組件指定一系列用于該組件的外聯(lián)樣式表文件。
@Component({
styleUrls:['app/list/item.component.css']
})
styles
和styleUrls
允許同時指定。如果同時指定,styles
中的樣式會先被解析,然后才會解析styleUrls
中的樣式,換句話說,styles
的樣式會被styleUrls
的樣式覆蓋。另外,也可以在模板的DOM節(jié)點上直接寫樣式,它的優(yōu)先級最高。
模板
每個組件都必須設置一個模板,angular才能將組件內容渲染到DOM上,這個DOM元素叫做宿主元素。組件可以與宿主元素交互,交互的形式包括:
- 顯示數(shù)據(jù):在模板中可以使用
{{}}
來顯示組件的數(shù)據(jù)。
//contactItem.component.ts
import { Component } from '@angular/core';
@Component({
selector:'contact-item',
template:`
<div>
<p>{{name}}</p>
<p>{{phone}}</p>
</div>
`
})
export class ContactItemComponent{
name:string='張三';
phone:string='13800000';
}
- 雙向數(shù)據(jù)綁定:
[(ngModel)]="property"
- 監(jiān)聽宿主元素事件以及調用組件方法:
(click)="addContact()"
組件與模塊
組件通過與其他組件協(xié)作,完成一個完整的功能特性。這樣的功能特性通常會封裝到一個模塊里。
模塊是在組建之上的一層抽象,組件以及指令、管道、服務、路由等都能通過模塊去組織。
模塊的構成
angular提供了@NgModule
裝飾器來創(chuàng)建模塊,一個應用可以有多個模塊,但有且只有一個根模塊,其他模塊叫做特性模塊。根模塊是啟動應用的入口模塊,根模塊必須通過bootstrap
元數(shù)據(jù)來指定應用的根組件,然后通過bootstrapModule()
方法來啟動應用。
//app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-brower';
import { ContactItemComponent } from './contactItem.component';
@NgModule({
imports:[BrowserModule],
declarations:[ContactItemComponent],
bootstrap:[ContactItemComponent]
})
export class AppModule {}
//app.ts
import { platformBrowseerDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
bootstrap
這個元數(shù)據(jù)用于指定應用的根組件,NgModule
主要的元數(shù)據(jù)如下。
- declarations:用于指定屬于這個模塊的視圖類,即指定哪些部件組成了這個模塊。angular有組件、指令和管道三種視圖類,這些視圖類只能屬于一個模塊,不能再次聲明屬于其他模塊的類。
- exports:導出視圖類。當該模塊被引入到外部模塊時,這個屬性指定了外部模塊可以使用該模塊的哪些視圖類,所以它的值類型跟
declarations
一致(組件、指令和管道)。 - imports:引入該模塊依賴的其他模塊或路由,引入后模塊里的組件模板才能引用外部對應的組件、指令和管道。
- providers:指定模塊依賴的服務,引入后該模塊中的所有組件都可以使用這些服務。
視圖類引入
NgModule
提供了declarations
這個元數(shù)據(jù)來將指令、組件或管道等視圖類引入到當前模塊。
在上面的AppModule
中,通過declarations
將ContactItemComponent
組件引入到了AppModule
模塊中,使得所有屬于AppModule
模塊的其它組件的模板都可以使用<contact-item>
。
//app.module.ts
@NgModule({
declarations:[
AppComponent,
ListComponent,
ListItemComponent,
DetailComponent,
CollectionComponent,
EditComponent,
HeaderComponent,
FooterComponent,
PhonePipe,
BtnClickDirective
]
//...
})
export class AppModule {}
如果在ListComponent
組件的模板代碼list.component.html
中,使用到了HeaderComponent
、FooterComponent
和ListItemComponent
這三個組件,這個時候必須在ListComponent
所屬的模塊(即AppModule
)中,通過declarations
引入這三個組件和ListItemComponent
組件后才能在模板中使用他們。
<!--list.component.html-->
<!--組件中制定了HeaderComponent,才能使用my-header標簽-->
<my-header title="所有聯(lián)系" [isShowCreateButton]="true"></my-header>
<ul class="list">
<li *ngFor="let contact of contacts">
<list-item [contact]="contact" (routerNavigate)="routerNavigate($event)"></list-item>
</li>
</ul>
<my-footer></my-footer>
ngFor
是angular的內置指令,在引入BrowserModule
的時候就已經(jīng)引入了常用的內置指令。
導出視圖類以及導入依賴模塊
有時候模塊中的組件、指令或管道,可能也會在其他模塊中使用??梢允褂?code>export元數(shù)據(jù)對外暴露這些組件、指令或管道。
//contact.module.ts
import { NgModule } from '@angular/core';
import { ContactItemComponent } from './contactItem.component';
@NgModule({
declarations:[ContactItemComponent],
exports:[ContactItemComponent] //導出組件
})
export class ContactModule {}
//message.module.ts
import { NgModule } from '@angular/core';
import { ContactModule } from './contact.module';
import { SomeOtherComponent } from './someother.component';
@NgModule({
//在SomeOtherComponent組件的模板中可以使用到<contact-item>組件了
declarations:[SomeOtherComponent],
imports:[ContactModule] //導入模塊
})
export class MessageModule {}
服務引入
服務通常用于處理業(yè)務邏輯及相關的數(shù)據(jù)。引入服務有兩種方式:一種是通過@NgModule
的providers
,另一種是通過@Component
的providers
。
//app.module.ts
import { ContactService } from './shared';
//...
@NgModule({
//...
providers:[ContactService],
bootstrap:[AppComponent]
})
export class AppModule {}
所有被包含在AppModule
中的組件,都可以使用到這些服務。同樣,在組件中也可以用providers
來引入服務,該組件及其子組件都可以公用這些引入的服務。
組件交互
組件交互就是組件通過一定的方式來訪問其他組件的屬性或方法,從而實現(xiàn)數(shù)據(jù)雙向流動。組件交互包括父子組件交互和一些非父子關系組件的交互。組件交互有很多方式,非父子關系的組件可以通過服務來實現(xiàn)數(shù)據(jù)交互通信。
組件的輸入輸出屬性
angular提供了輸入(@Input
)和輸出(@Output
)語法來處理組件數(shù)據(jù)的流入流出。
//item.component.ts
export class ListItemComponent implements OnInit {
@Input() contact:any={};
@Output() routerNavigate=new EventEmitter<number>();
}
<!--list.component.html-->
<li *ngFor="let contact of contacts">
<list-item [contact]="contact" (routerNavigate)="routerNavigate($event)">
</list-item>
</li>
ListItemComponent
組件的作用是顯示單個聯(lián)系人的信息。由于聯(lián)系人列表數(shù)據(jù)是在ListCommponent
組建中維護的,在顯示單個聯(lián)系人時,需要給ListItemComponent
傳入單個聯(lián)系人數(shù)據(jù)。另外在單擊單個聯(lián)系人時,需要跳轉到此聯(lián)系人的明細信息,需要子組件通知父組件進行跳轉,[contact]
和(routerNavigate)
的輸入輸出變量,用于滿足上述功能。
這里的輸入輸出是以當前組件角度去說的,contact
和routerNavigate
分別是ListItemComponent
組件的輸入和輸出屬性。輸出屬性一般是以事件的形式,將數(shù)據(jù)通過EventEmitter
拋出去。
除了使用@Input
和@Output
修飾外,還可以在組件的元數(shù)據(jù)中使用inputs
、output
來設置輸入輸出屬性,設置的值必須為字符串數(shù)組,元素的名稱需要和成員變量相對應。
@Component({
inputs:['contact'],
outputs:['routerNavigate']
})
export class ListItemComponent implements OnInit {
contact:any={};
routerNavigate=new EventEmitter<number>();
}
父組件向子組件傳遞數(shù)據(jù)
父組件的數(shù)據(jù)通過子組件的輸入屬性流入子組件,在子組件完成接收或攔截,以此實現(xiàn)了數(shù)據(jù)由上而下的傳遞。
父到子組件間的數(shù)據(jù)傳遞
父組件LIstComponent
將獲取到聯(lián)系人的數(shù)據(jù),通過屬性綁定的方式流向子組件ListItemComponent
。
//list.component.ts
import { Component,OnInit } from '@angular/core';
@Component({
selector:'list',
template:`
<ul class="list">
<li *ngFor="let contact of contacts">
<list-item [contact]="contact"></list-item>
</li>
</ul>
`
})
export class ListComponent implements OnInit {
this.contacts=data;//data為獲取到的聯(lián)系人數(shù)據(jù)
}
//item.component.ts
import { Component,OnInit,Input } from '@angular/core';
@Component({
selector:'list-item',
template:`
<div class="contact-info">
<label class="contact-name">{{contact.name}}</label>
<span class="contact-tel">{{contact.telNum}}</span>
</div>
`
})
export class ListItemComponent implements OnInit {
@Input() contact:any={};
}
在之前的例子中,app.module.ts
中已經(jīng)通過@NgModule
的元數(shù)據(jù)declarations
將子組件ListItemComponent
的實例引入到AppModule
中,使得所有屬于AppModule
中的其他組件都可以使用ListItemComponent
組件,因此在父組件ListComponent
中可直接引用該子組件。將每個聯(lián)系人對象通過屬性綁定的方式綁定到屬性contact
中來供子組件來引用,數(shù)據(jù)由上而下流入子組件,在子組件中通過@Input
裝飾器進行數(shù)據(jù)的接收。
攔截輸入屬性
子組件可以攔截輸入屬性的數(shù)據(jù)并進行相應的處理。有兩種攔截處理方式。
1.setter攔截輸入屬性
getter
和setter
通常配套使用,用來對屬性進行相關約束。他們提供了一些屬性讀寫的封裝。setter可以對屬性進行再封裝處理,對復雜的內部邏輯通過訪問權限控制來隔絕外部調用,以避免外部的錯誤調用影響到內部的狀態(tài)。同時也把內部復雜的邏輯結構封裝成高度抽象可被簡單調用的屬性,再通過getter
返回要設置的屬性值。
通過輸入輸出屬性可以實現(xiàn)父子組件的數(shù)據(jù)交互,還可以通過setter
來攔截來自父組件的數(shù)據(jù)源,并進行處理,使數(shù)據(jù)的輸出更合理。
//ListComponent.ts使用前面的例子
//ListItem.component.ts
@Component({
selector:'list-item',
template:`
<div>
<label class="contact-name">{{contactObj.name}}</label>
<span class="contact-tel">{{contactObj.telNum}}</span>
</div>
`
})
export class ListItemComponent implements OnInit{
_contact:object={};
@Input()
set contactObj(contact:object){
this._contact.name=(contact.name&&contact.name.trim())||'no name seet';
this._contact.telNum=contact.telNum||'000-000';
}
get contactObj(){ return this._contact; }
}
這里通過setter
的方式設置一個contactObj
屬性對象,其作用是對通過@Input
修飾符獲取的數(shù)據(jù)contact
進行二次處理,再通過getter
返回這個contactObj
對象。這樣處理的作用是使得聯(lián)系人不會出現(xiàn)null
或undefined
的情況。getter
和setter
其實是在組件類的原型對象上設置了一個contactObj
屬性。
Object.defineProperty(ListItemComponent.prototype,"contactObj",{
//...
})
2.ngOnChanges監(jiān)聽數(shù)據(jù)變化
ngOnChanges
用于及時響應angular在屬性綁定中發(fā)生的數(shù)據(jù)變化,該方法接收一個對象參數(shù),包含當前值和變化前的值。在ngOnInit
之前,或者當數(shù)據(jù)綁定的輸入屬性的值發(fā)生變化時會觸發(fā)。ngOnChanges
是組件的生命周期鉤子之一。
//父組件detail.component.ts
import { Component } from '@angular/core';
@Component({
selector:'detail',
template:`
<a class="edit" (click)="editContact()">編輯</a>
<change-log [contact]="detail"></change-log>
`
})
export class DetailComponent implements OnInit{
detail:any={};
//完成聯(lián)系人編輯修改
editContact(){
//...
this.detail=data;//修改后的數(shù)據(jù)
}
}
//子組件changelog.component.ts
import { Component,Input,OnChanges,SimpleChanges } from '@angular/core';
@Component({
selector:'change-log',
template:`
<h4>Change log:</h4>
<ul>
<li *ngFor="let change of changes">{{change}}</li>
</ul>
`
})
export class ChangeLogComponent implements OnChanges{
@Input() contact:any={};
changes:string[]=[];
ngOnChanges(changes:{[propKey:string]:SimpleChanges}){
let log:string[]=[];
for(let propName in changes){
let changedProp=changes[propName],
from=JSON.stringify(changedProp.previousValue),
to=JSON.stringify(changedProp.currentValue);
log.push(`${propName} changed from ${from} to ${to}`);
}
this.changes.push(log.join(', '));
}
}
SimpleChanges
類是angular的一個基礎類,用于處理數(shù)據(jù)的前后變化,其包含兩個重要成員變量,分別是previousValue
和currentValue
,previousValue
是獲取變化前的數(shù)據(jù),currentValue
是獲取變化后的數(shù)據(jù)。
ngOnChanges
當且僅當組件輸入數(shù)據(jù)變化時被調用,“輸入數(shù)據(jù)”指的是通過@Input
裝飾器顯式指定的那些數(shù)據(jù)。
子組件向父組件傳遞數(shù)據(jù)
使用事件傳遞是子組件向父組件傳遞數(shù)據(jù)的最常用方式。子組件需要實例化一個用來訂閱和觸發(fā)自定義事件的EventEmitter
類,這個實例對象是一個由裝飾器@Output
修飾的輸出屬性,當有用戶操作行為發(fā)生時該事件會被觸發(fā),父組件則通過事件綁定的方式來訂閱來自子組件觸發(fā)的事件。
//collection.component.ts 父組件
import { Component } from '@angular/core';
@Component({
selector:'collection',
template:`
<contact-collect [contact]="detail" (onCollect)="collectTheContact($event)">
</contact-collect>
`
})
export class CollectionComponent implements OnInit{
detail:any={};
collectTheContact(){
this.detail.collection==0?this.detail.collection=1:this.detail.collection=0;
}
}
父組件CollectionComponent
通過綁定自定義事件onCollect
訂閱來自子組件觸發(fā)的事件。當有來自子組件對應的事件被觸發(fā),在父組件中能夠監(jiān)聽到該事件。
//contactCollect.component.ts 子組件
import { Component,EventEmitter,Input,Output } from '@angular/core';
@Component({
selector:'contact-collect',
template:`
<i [ngClass]="{collected:contact.collection}" (click)="collectTheContact()"收藏</i>
`
})
export class ContactCollectComponent {
@Input() contact:any={};
@Output() onCollect=new EventEmitter<boolean>();
collectTheContact(){
this.onCollect.emit();
}
}
其他組件交互方式
父子組件間數(shù)據(jù)傳遞的實現(xiàn)還有兩種方式:
- 父組件通過局部變量獲取子組件引用
- 父組件使用
@ViewChild
獲取子組件的引用
通過局部變量實現(xiàn)數(shù)據(jù)交互
模板局部變量可以獲取子組件的實例引用。通過創(chuàng)建模板局部變量的方式,來實現(xiàn)父組件與子組件數(shù)據(jù)交互,即在父組件的模板中為子組件創(chuàng)建一個局部變量,這個父組件可以通過這個局部變量來獲得讀取子組件公共成員變量和函數(shù)的權限。模板局部變量的作用域范圍僅存在于定義該模板局部變量的子組件。
//父組件collection.component.ts
import { Component } from '@angular/core';
@Component({
selector:'collection',
template:`
<contact-collect (click)="collectTheContact()" #collect></contact-collect>
`
})
export class CollectionComponent {}
//子組件contactcollect.component.ts
import { Component } from '@angular/core';
@Component({
selector:'contact-collect',
template:`
<i [ngClass]="{collect:detail.collection}">收藏</i>
`
})
export class ContactCollectComponent{
detail:any={};
collectTheContact() {
this.deetail.collection==0?this.detail.collection=1:this.detail.collection=0;
}
}
這里通過在標簽元素<contact-collect>
中放置一個局部變量collect
,用來獲取子組件的實例引用,來訪問子組件中的成員變量和方法。
使用@ViewChild實現(xiàn)數(shù)據(jù)交互
當父組件需要獲取到子組件中變量或方法的讀寫權限時,可以通過@ViewChild
注入的方式來實現(xiàn)。組件中元數(shù)據(jù)ViewChild
的作用是聲明對子組件元素的實例引用,它提供了一個參數(shù)來選擇將要引用的組件元素,這個參數(shù)可以是一個類的實例,也可以是一個字符串。
- 參數(shù)為類實例,表示父組件將綁定一個指令或子組件實例
- 參數(shù)為字符串類型,表示將起到選擇器的作用,即相當于在父組件中綁定一個模板局部變量,獲取到子組件的一份實例對象的引用
組件中元數(shù)據(jù)ViewChild
的參數(shù)為字符串的實現(xiàn)方式和綁定模板局部變量是一樣的。
import { Component,AfterViewInit,ViewChild } from '@angular/core';
@Component({
selector:'collection',
template:`
<contact-collect (click)="collectTheContact()"></contact-collect>
`
})
export class CollectionComponent{
@ViewChild(ContactCollectComponent) contactCollect:CotactCollectComponent;
ngAfterViewInit(){
//...
}
collectTheContact(){
this.contactCollect.collectTheContact();
}
}
組件內容嵌入
內容嵌入通常用來創(chuàng)建可復用組件。
import { Component } from '@angular/core';
@Component({
selector:'example-content',
template:`
<div>
<h4>ng-content 示例</h4>
<div style="background-color:gray;padding:5px;margin:2px">
<ng-content select="header"></ng-content>
</div>
</div>
`
})
class NgContentExampleComponent {}
接著再定義一個根組件來使用它。
import { Component } from 'angular/core';
@Component({
selector:'app',
template:`
<example-content>
<header>Header content</header>
<!--將自定義的內容放到 example-content標簽之間-->
</example-content>
`
})
export class NgContentAppComponent {}
最后組件的DOM樹會被渲染成:
<app>
<example-content>
<div>
<h4>ng-content示例</h4>
<div style="background-color:gray;padding:5px;margin:2px">
<ng-content select="header"></ng-content>
</div>
</div>
<example-content>
</app>
<example-content>
標簽之間的內容,也就是<header>Header content</header>
,被填充到ng-content
,而NgContentExampleComponent
組件模板中的其他元素沒有受到影響。select="header"
表示匹配<example-content>
標簽之間的第一個header
標簽,并將其填充到相應的ng-content
中。
還可以同時使用多個嵌入內容。
import { Component } from '@angular/core';
@Component({
selector:'example-content',
template:`
<div>
<h4>component with ng-content</h4>
<div style="background-color:green;padding:5px;margin:2px">
<ng-content select="header"></ng-content>
</div>
<div style="background-color:gray;padding:5px;margin:2px">
<ng-content select=".class-select"></ng-content>
</div>
<div style="background-color:blue;padding:5px;margin:2px">
<ng-content select="[name=footer]"></ng-content>
</div>
</div>
`
})
class NgContentExampleComponent {}
//NgContemtAppComponent.ts
import { Component } from 'angular/core';
@Component({
selector:'app',
template:`
<example-content>
<header>Header content</header>
<div class="class-select">div with .class-content</div>
<div name="footer">Footer content</div>
</example-content>
`
})
export class NgContentAppComponent {}
組件生命周期
組件的生命周期由angular內部管理,從組件的創(chuàng)建、創(chuàng)建,到數(shù)據(jù)變動事件的觸發(fā),再到組件從DOM中移除,angular都提供了一系列鉤子。這些鉤子可以在這些事件觸發(fā)時,執(zhí)行相應的回調函數(shù)。
生命周期鉤子
鉤子的接口包含@angular/core
中。每個接口都對應一個名為ng+接口名
的方法。
class ExampleInitHook implements OnInit {
constructor() {}
ngOnInit() {
console.log('OnInit');
}
}
以下是組件常用的生命周期鉤子方法,angular會按以下的順序依次調用鉤子方法:
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngOnDestroy
除此之外,有的組件還提供了自己特有的生命周期鉤子,例如路由有routerOnActivate
鉤子。
ngOnChanges
ngOnChanges
鉤子用來響應組件輸入值發(fā)生變化時觸發(fā)的事件。該方法接收一個SimpleChanges
對象,包含當前值和變化前的值。該方法在ngOnInit
之前,或者當數(shù)據(jù)綁定輸入屬性的值發(fā)生變化時觸發(fā)。
只要在組件里定義了ngOnChanges
方法,在輸入數(shù)據(jù)發(fā)生變化時該方法就會被自動調用。這里的“輸入數(shù)據(jù)”指的是通過@Input
裝飾器顯示指定的變量。
ngOnInit
ngOnInit
鉤子用于數(shù)據(jù)綁定輸入屬性之后初始化組件。該鉤子方法會在第一次ngOnChanges
之后被調用。
使用ngOnInit
有兩個重要原因:
- 組件構造后不久就要進行復雜的初始化
- 需要在輸入屬性設置完成之后才構建組件
在組件中,經(jīng)常會使用ngOnInit
獲取數(shù)據(jù)。
ngDoCheck
用于變化監(jiān)測,該鉤子方法會在每次變化監(jiān)測發(fā)生時被調用。
每一個變化監(jiān)測周期內,不管數(shù)據(jù)值是否發(fā)生了變化,ngDoCheck
都會被調用。但要慎用,例如鼠標移動時會觸發(fā)mousemove
事件,此時變化監(jiān)測會被頻繁觸發(fā),隨之ngDoCheck
也會被頻繁調用。因此,ngDoCheck
方法中不能寫復雜的代碼,否則性能會受影響。
絕大多數(shù)情況下,ngDoCheck
和ngOnChanges
不應該一起使用。ngOnChanges
能做的事,ngDoCheck
也能做到,而ngDoCheck
監(jiān)測的力度更小,可完成更靈活的變化監(jiān)測邏輯。
ngAfterContentInit
在組件中使用<ng-content>
將外部內容嵌入到組件視圖后就會調用ngAfterContentInit
,它在第一次ngDoCheck
執(zhí)行后調用,且只執(zhí)行一次。
ngAfterContentChecked
在組件使用了<ng-content>
自定義內容的情況下,angular在這些外部內容嵌入到組件視圖后,或每次變化監(jiān)測的時候都會調用ngAfterContentChecked
。
ngAfterViewInit
ngAfterViewInit
會在angular創(chuàng)建了組件的視圖及其子視圖之后被調用。
ngAfterViewChecked
ngAfterViewChecked
在angular創(chuàng)建了組件的視圖及其子組件視圖之后被調用一次,并且在每次子組件變化監(jiān)測時也會被調用。
ngOnDestroy
ngOnDestroy
在銷毀指令/組件之前觸發(fā)。那些不會被垃圾回收器自動回收的資源(如已訂閱的觀察者事件、綁定過的DOM事件、通過setTimeout
或setInterval
設置過的計時器等)都應當在ngOnDestroy
中手動銷毀掉,從而避免發(fā)生內存泄漏等問題。