angular 輸入屬性@Input , 輸出屬性@Output , 中間人模式


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>

效果顯示

這里寫圖片描述 
點擊“立即購買”按鈕,下單組件就可以接收到報價組件的實時信息。

小結

這樣中間人模式就實現了,兩個組件之間不需要指導彼此的存在就可以傳遞數據,增強組件的重用性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM