1 輸入屬性
通常用於父組件向子組件傳遞信息
舉個栗子:我們在父組件向子組件傳遞股票代碼,這里的子組件我們叫它app-order
首先在app.order.component.ts中聲明需要由父組件傳遞進來的值
order.component.ts
...
@Input()
stockCode: string @Input() amount: string ...
order.component.html
<p>這里是子組件</p> <p>股票代碼為{{stockCode}}</p> <p>股票總數為{{amount}}</p>
然后我們需要在父組件(app.component)中向子組件傳值
app.component.ts
...
stock: string ...
app.component.html
<input type="text" placeholder="請輸入股票代碼" [(ngModel)]="stock"> <app-order [stockCode]="stock" [amount]="100"></app-order>
這里我們使用了Angular的雙向數據綁定,將用戶輸入的值和控制器中的stock進行綁定。然后傳遞給子組件,子組件接收后在頁面顯示。
2 輸出屬性
當子組件需要向父組件傳遞信息時需要用到輸出屬性。
舉個栗子:當我們從股票交易所獲得股票的實時價格時,希望外部也可以得到這個信息。為了方便,這里的實時股票價格我們通過一個隨機數來模擬。這里的子組件我們叫它app.price.quote
使用EventEmitter從子組件向外發射事件
price.quote.ts
export class PriceQuoteComponent implements OnInit{
stockCode: string = 'IBM'; price: number; //使用EventEmitter發射事件 //泛型是指往外發射的事件是什么類型 //priceChange為事件名稱 @Output() priceChange:EventEmitter<PriceQuote> = new EventEmitter(); constructor(){ setInterval(() => { let priceQuote = new PriceQuote(this.stockCode, 100*Math.random()); this.price = priceQuote.lastPrice; //發射事件 this.priceChange.emit(priceQuote); }) } ngInit(){ } } //股票信息類 //stockCode為股票代碼,lastPrice為股票價格 export class PriceQuote{ constructor(public stockCode:string, public lastPrice:number ) }
price.quote.html
<p>
這里是報價組件
</p>
<p> 股票代碼是{{stockCode}} </p> <p> 股票價格是{{price | number:'2.2-2'}} </p>
接着我們在父組件中接收事件
app.component.html
<app-price-quote (priceChange)="priceQuoteHandler($event)"></app-price-quote>
<div>
這是在報價組件外, 股票代碼是{{priceQuote.stokcCode}},
股票價格是{{priceQuote.lastPrice | number:'2.2-2'}} </div>
事件綁定和原生的事件綁定是一樣的,都是將事件名稱放在()中。
app.component.ts
export class AppComponent{
priceQuote:PriceQuote = new PriceQuote('', 0); priceQuoteHandler(event:PriceQuote){ this.priceQuote = event; } }
這里的event類型就是子組件傳遞事件的類型。
簡單的說,就是子組件通過emit發射事件priceChange,並將值傳遞出來,父組件在使用子組件時會觸發priceChange事件,接收到值。
3 中間人模式
組件之間可以通過建立父子關系來傳遞數據,但是這樣兩個組件之間的耦合性太強,重用性太低。那么如果組件間不存在關系,可以傳遞數據嗎?如何傳遞呢?
中間人模式,顧名思義,就是兩個組件之間通過一個中間人來傳遞數據,兩個組件之間不需要知道彼此的存在,中間人接收一個組件的數據傳遞給另一個組件。
場景
交易員監看報價組件的價格,但股票的價格達到某一個值的時候,交易員會點一個交易按鈕來購買股票,報價組件通知中間人交易員要購買股票,中間人知道哪個組件可以完成下單,並將股票價格傳遞該組件
實現
1、報價組件
(1) 添加購買按鈕
<div> 我是報價組件 </div> <div> 股票代碼是{{stockCode}},股票價格是{{price | number:'2.2-2'}} </div> <div> <input type="button" value="立即購買" (click)="buyStock($event)"> </div>
(2) 然后報價組件將當前股票價格發射出去
//用來發射報價 @Output() buy:EventEmitter<PriceQuote> = new EventEmitter(); constructor() { setInterval(() => { // 聲明一個priceQuote變量 let priceQuote:PriceQuote = new PriceQuote(this.stockCode, 100*Math.random()); this.price = priceQuote.lastPrice; // 用emit方法發射事件的時候,就是這個泛型<PriceQuote>所制定的變量priceQuote的數據 this.lastPrice.emit(priceQuote); },1000) } //這就是報價組件做的事,只要把價格發射出去就行,不管誰去接收(應該是中間人去接收,也就是app組件) //點擊按鈕時,用buy.emit把當前股票價格發射出去 buyStock(event){ this.buy.emit(new PriceQuote(this.stockCode,this.price)); }
2、中間人接收(app組件),並傳給下單組件
<!-- 監聽buy事件,並接收數據,然后通過屬性綁定傳給下單組件 --> <app-price-quote (buy)="buyHandler($event)"></app-price-quote> <app-order [priceQuote]='priceQuote'></app-order> export class AppComponent { stock = ""; //給本地的priceQuote設置默認值 priceQuote:PriceQuote = new PriceQuote("",0); // 在priceQuoteHandler方法中接收event,event類型就是PriceQuote類型的(子組件中發射出的類型) buyHandler(event:PriceQuote){ // 然后讓本地的priceQuote等於捕獲的event this.priceQuote = event; } }
3、下單組件,接收中間人傳來的數據,並顯示
(1) 接收
@Input()
priceQuote:PriceQuote;
(2) 顯示
<div> 我是下單組件 </div> <div> <!-- 綁定屬性 --> 賣100手{{priceQuote.stockCode}}股票,買入價格是{{priceQuote.lastPrice | number:'2.2-2'}} </div>
效果顯示
點擊“立即購買”按鈕,下單組件就可以接收到報價組件的實時信息。
小結
這樣中間人模式就實現了,兩個組件之間不需要指導彼此的存在就可以傳遞數據,增強組件的重用性。