How Angular Works
這部分注重給一個全面而基礎的部分。最重要點就是Angular是由組件組成。
Application
應用是最終形態,它是由一連串的組件組成樹形結構。
在結構根部,最高級別組件就是應用自己,也就是瀏覽器啓動這個app的地方。
組件的一個重要特性就是可以組成,就是可以通過一個個小組件組成一個大組件。
因爲是樹形結構,所以由父組件,子組件組成。父組件逐層渲染子組件。
如下是一個例子,把它分成組件。
可首先分爲3層,
1. 導航欄
2. 麪包屑
3. 產品列表
其中產品列表是一系列產品集合,多個產品行,multiple Product Rows
每一行,由產品圖片,產品信息分類,價格組成
最終集合到一起
這一章節主要解釋
- 如何把應用拆解成組件
- 如何用
input
重複利用組件 - 如何處理用戶交互,比如組件上的
click
產品模型
Angular的一個重要特點就是不提供一個具體的模型庫。它靈活的支持各類模型和數據結構。
用戶需要決定如何搭建和使用。
如下, 建造一個product
模型,接受5個參數
用public
聲明表示這是全局變量
export class Product {
constructor(
public sku: string,
public name: string,
public imageUrl: string,
public department: string[],
public price: number) {
}
}
之前提到過,Anjular應用是由組件搭建而成。而應用本身就是最高級別組件。
每一個組件有3部分組成
- Component Decorator
- View
- Controller
一個基本top-level AppComponent 如下
@Component({
selector: 'inventory-app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
@Component
就是 Decorator,它的裝飾器包括:
- selector
: 告訴Angular匹配那一個元素
- templateUrl
:定義view
controller
是由對應的class
定義
組件裝飾器 Component Decorator
@Component
裝飾器負責配置組件。
selector
設置模版的tag
,用於HTML引用。
定義HTML的哪些元素匹配這個component。
比如selector: 'inventory-app-root',
就是告訴HTML有如下tag
<inventory-app-root></inventory-app-root>
HTML也可以這麼引用:
<div inventory-app-root></div>
template
定義HTML頁面
可以在template直接輸入
或者引用
add data and view
模型已建好,需要添加一條數據,
可以在component裏引入模型添加數據 p90
一條數據直接(), 多條用數組[]
import { Product } from './product.model';
class AppComponent {
product: Product[];
constructor() {
this.product = new Product[
new Product(
'MYSHOES',
'Black Running Shoes',
'/assets/images/products/black-shoes.jpg',
['Men', 'Shoes', 'Running Shoes'],
109.99),
new Product(
...
]
}
}
在HTML頁面引入數據
<h1>{{ product.name }}</h1>
<span>{{ product.sku }}</span>
click it
做一個選擇按鈕,
先在component定義函數
productWasSelected(product: Product): void {
console.log('Product clicked: ', product);
}
product list component
計劃創建produce-list
組件用來顯示produce list
但是在之前,現在appcomponent組件下定義:
<div class="inventory-app">
<products-list
[productList]="products" //input
(onProductSelected)="productWasSelected($event)"> //outut
</products-list>
</div>
組件之間數據綁定
在Angular中
[]處理input
子組件接收數據
父組件通過[]來把數據傳到子組件
在本例中
[productList]="products"
左邊 [productList]表示用productList
來作爲produce-list
組件的輸入
右邊“products”要傳輸的目標對象,也就是AppComponent組件的this.products
.
如何知道productList是produce-list組件的輸入名?
在組件的文檔中定義,input和output會作爲類似於public API被定義。
()處理output
子組件發送數據
本例中
(onProductSelected)="productWasSelected($event)">
監聽組件的onProductSelected
,
右邊productWasSelected
表示output接收數據時,觸發的函數,來自AppComponent組件
$event 表示傳輸的變量/變量
再創建produce-list
組件 p98
再組件定義
...
export class ProductsListComponent {
@Input() productList: Product[];
@Output() onProductSelected: EventEmitter<Product>;
通過 ProductsListComponent
的input傳遞this.products
(AppComponent)
在product-list組件 導入模型
並設置
...
export class ProductsListComponent {
@Input() productList: Product[];
...
在product-list組件的html裏
<div
*ngFor="let myProduct of productList"
[product]="myProduct"> //[product]來自於product-row組件
</div>
Output的輸出語法是 (output)=”action”
一個output需要3個部分
1, 在組件定義output
2, 配置一個事件觸發器EventEmitter
3,從事件觸發器里正確的觸發事件
EventEmitter是時間觸發器,一個對象用來執行觀察模式,用來
1. 保持訂閱列表
2. 發表事件
比如
letee=newEventEmitter();
ee.subscribe((name:string)=>console.log(`Hello${name}`));
ee.emit("Nate");
// "Hello Nate"
時間觸發器的使用p102 p125
HostBinding
p110, p133
宿主綁定,繼承父組件的元素設置
設置ProductRowComponent組件
分爲3個子組件
在image組件中,導入img
, p111, p134
設置模版
<img class="product-image" [src]="product.imageUrl">
或者
<img src="{{ product.imageUrl }}">
設置產品分類麪包屑
<span *ngFor="let name of product.department; let i=index">
<a href="#">{{ name }}</a>
<span>{{i < (product.department.length-1) ? '>' : ''}}</span>
</span>
如下
Women > Apparel > Jackets & Vests
app啓動程序
ng serve -> .angular-cli.json -> main.ts -> AppModule -> ….