Angular組件間通信css
組件樹,1號是根組件AppComponent。html
組件之間鬆耦合,組件之間知道的越少越好。編程
組件4裏面點擊按鈕,觸發組件5的初始化邏輯。數據結構
傳統作法:在按鈕4的點擊事件裏調用組件5的方法。緊密耦合。app
Angular:在組件4根本不知道組件5存在的狀況下實現。dom
使用鬆耦合的方式在組件之間傳遞數據開發出高重用性的組件。學習
使用輸入輸出屬性在父子關係的組件之間傳遞數據。this
組件設計成黑盒模型,用輸入屬性聲明從外部世界接收什麼東西。不須要知道這些東西從哪裏來來。spa
組件只須要知道當它須要的東西外部世界提供給它之後它應該怎麼作。設計
組件經過輸出屬性發射事件告訴外部世界可能感興趣的東西。至於事件發射給誰組件也不須要知道。
誰感興趣誰本身訂閱組件發射的事件。
子組件定義了2個輸入屬性,被@Input()裝飾器裝飾的屬性。
@Input()
stockCode:string;
@Input()
amount:number;
父組件經過屬性綁定到子組件輸入屬性的方式把stock屬性綁定到子組件的stockCode屬性上。
<div> 我是父組件 </div> <div> <input type="text" [(ngModel)]="stock" placeholder="請輸入股票代碼"> <app-order [stockCode]=stock [amount]="100"></app-order> </div>
每隔3s重置子組件的stockCode的值爲Apple。
export class OrderComponent implements OnInit { @Input() stockCode:string; @Input() amount:number; constructor() { setInterval(()=>{ this.stockCode='Apple' },3000) } ngOnInit() { } }
當子組件的stockCode的值變爲Apple的時候,父組件的stock的值並無改變。說明綁定是單向的,只能是父組件改變子組件,子組件屬性改變不會影響到父組件。
Angular組件可使用EventEmitter對象發射自定義事件,這些事件能夠被其它組件處理。 EventEmitter是Rxjs中Subject類的一個子類,在響應式編程中,它既能夠做爲被觀察者,也能夠做爲觀察者。就是說EventEmitter對象便可以經過它的emit方法發射自定義事件,也能夠經過subscribe方法來訂閱EventEmitter發射出來的事件流。
如何使用EventEmit從組件內部向外發射事件?
例子場景:報價組件
假設須要一個組件,能夠鏈接到股票交易所,而且實時的顯示變更的股票價格,爲了讓這個組件能夠在不一樣的金融類的應用中重用,除了實時顯示股票價格,組件還應該將最新的股票價格發送到組件以外,這樣其它的組件就能夠針對變更的股票價格執行相應的業務邏輯。
export class PriceQuoteComponent implements OnInit { //不鏈接股票服務,用一個隨機數生成器模擬股票價格的變化,並將股票代碼和最新的價格顯示出來 stockCode:string="IBM"; price:number; constructor() { setInterval(()=>{ let priceQuote:PriceQuote=new PriceQuote(this.stockCode,100*Math.random()); this.price=priceQuote.lastPrice; },1000) } ngOnInit() { } } //封裝一個報價對象來封裝股票價格信息 //將特定的數據結構用類或接口來明肯定義是一個良好的習慣 export class PriceQuote { constructor(public stockCode: string, //股票代碼 public lastPrice: number //最新價格 ) { } }
EventEmit後面的範型是要往出發射的事件的數據是什麼類型的。
import { Component, OnInit, EventEmitter, Output } from '@angular/core'; @Component({ selector: 'app-price-quote', templateUrl: './price-quote.component.html', styleUrls: ['./price-quote.component.css'] }) export class PriceQuoteComponent implements OnInit { //不鏈接股票服務,用一個隨機數生成器模擬股票價格的變化,並將股票代碼和最新的價格顯示出來 stockCode: string = "IBM"; price: number; @Output() //發射事件須要寫上Output //EventEmitter須要一個範型 lastPrice: EventEmitter<PriceQuote> = new EventEmitter(); // constructor() { setInterval(() => { let priceQuote: PriceQuote = new PriceQuote(this.stockCode, 100 * Math.random()); this.price = priceQuote.lastPrice; //用lastPrice emit一個值出去 this.lastPrice.emit(priceQuote); }, 1000) } ngOnInit() { } }
//封裝一個報價對象來封裝股票價格信息 //將特定的數據結構用類或接口來明肯定義是一個良好的習慣 export class PriceQuote { constructor(public stockCode: string, //股票代碼 public lastPrice: number //最新價格 ) { } }
父組件模版中經過事件綁定的方式來捕獲並處理。
export class AppComponent { stock = ""; priceQuote: PriceQuote = new PriceQuote("", 0); //event的類型就是子組件emit的時候發射出來的數據的類型 //父組件中經過event就能夠拿到 priceQuoteHandler(event:PriceQuote){ this.priceQuote=event; } }
模版
<!--默認狀況下,事件名字就是output輸出屬性的名字--> <app-price-quote (lastPrice)="priceQuoteHandler($event)"></app-price-quote> <div> 這是在報價組件外部<br/> 股票代碼是{{priceQuote.stockCode}}, 股票價格是{{priceQuote.lastPrice | number:"2.0-2"}} </div>
默認狀況下,事件名字就是output輸出屬性的名字,能夠改變事件名字,經過
@Output("priceChange") //發射事件須要寫上Output //EventEmitter須要一個範型 lastPrice: EventEmitter<PriceQuote> = new EventEmitter();
模版中也改成
<app-price-quote (priceChange)="priceQuoteHandler($event)"></app-price-quote>
總結:經過輸出屬性發射事件,並經過事件攜帶數據,在父組件模版中經過事件綁定的方式來捕獲並處理。
若是兩個組件之間不存父子關係,如何以一種鬆耦合的方式來傳遞數據。此時須要使用中間人模式。
本文做者starof,因知識自己在變化,做者也在不斷學習成長,文章內容也不定時更新,爲避免誤導讀者,方便追根溯源,請諸位轉載註明出處:http://www.cnblogs.com/starof/p/8636579.html 有問題歡迎與我討論,共同進步。