Angular應用由組件(Component)構成。它與AngularJS中的指令相似(directive)。 應用 一個Angular應用本質上是一個組件樹。在組件樹的頂層,最上級的組件即是應用本身。當啟動此應用時,瀏覽器將渲染這個頂層組件。 Angular組件的重要特性是其可按照父子樹的結構自由 ...
Angular應用由組件(Component)構成。它與AngularJS中的指令相似(directive)。
應用
一個Angular應用本質上是一個組件樹。在組件樹的頂層,最上級的組件即是應用本身。當啟動此應用時,瀏覽器將渲染這個頂層組件。
Angular組件的重要特性是其可按照父子樹的結構自由組合,當每個組件渲染時,也會遞歸渲染其子組件。
假設有一個庫存管理的應用,如下圖所示:
在開始寫應用時,首先應該將其拆成三個組件。
標簽導航組件:
麵包屑導航組件:
產品列表組件:
再進一步拆分的話,產品列表由多個產品行構成。
而產品行又可以拆成產品圖片,產品所屬,價格顯示這件小組件。
所以最終應用的樹圖是這樣的:
組件
每個組件包含三部分:
- 組件裝飾器(Component Decorator)
- 視圖(View)
- 控制器(Controller)
以最上層的應用組件為例,這個組件的代碼可能是這樣的:
@Component({
selector: 'inventory-app-root',
template: `
<div class="inventory-app">
(Products will go here soon)
</div>
`
})
export class AppComponent {
}
@Component
就是組件裝飾器,它為AppComponent類添加元數據。
上例的@Component
裝飾器指定了選擇器(selector)——告訴Angular匹配何種元素(element),以及模板(template)——定義了視圖。
模板內容可以置於其它的文件中,這時需要使用templateUrl替代template。
@Component({
selector: 'inventory-app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
}
組件控制器通過類(class)來定義,上例的AppComponent類即是控制器。
假設要在AppComponent組件對應的視圖中顯示產品的信息,可以通過模板綁定的方式達成此目的。
<div class="inventory-app">
<h1>{{ product.name }}</h1>
<span>{{ product.sku }}</span>
</div>
{{ … }}語法被稱為模板綁定,它會告訴視圖使用模板中的特定數據。
組件中的核心特性之一是輸入(input)與輸出(output)。
<div class="inventory-app">
<products-list
[productList]="products"
(onProductSelected)="productWasSelected($event)">
</products-list>
</div>
方括弧傳送輸入,圓括弧處理輸出。
藉由輸入綁定數據進入組件,通過輸出綁定事件流出組件。
在Angular中,父組件通過輸入傳送數據給子組件,而子組件則通過輸出傳送數據給父組件。
需要接收數據的子組件要由@Input()
裝飾器指明對應的屬性。如下例:
import { Component, Input } from '@angular/core';
@Component({
selector: 'my-component',
})
class MyComponent {
@Input() name: string;
@Input() age: number;
}
而要讓父組件接收數據的子組件要使用@output()
裝飾器。
@Component({
selector: 'single-component',
template: `
<button (click)="liked()">Like it?</button>
`
})
class SingleComponent {
@Output() putRingOnIt: EventEmitter<string>;
constructor() {
this.putRingOnIt = new EventEmitter();
}
liked(): void {
this.putRingOnIt.emit("oh oh oh");
}
}
例子中的子組件需要完成三步操作,指定輸出屬性(使用@output()
標註);創建EventEmitter對象並綁定到對應輸出屬性;當特定方法(比如liked())被調用時發出事件。
@Component({
selector: 'club',
template: `
<div>
<single-component
(putRingOnIt)="ringWasPlaced($event)"
></single-component>
</div>
`
})
class ClubComponent {
ringWasPlaced(message: string) {
console.log(`Put your hands up: ${message}`);
}
}
父組件中$event包含了由子組件傳回的數據。