前言
在 Angular 內,第三種資料繫結的方法是事件繫結 ( Event Binding ),具體來說怎麼實踐,讓我們繼續看下去。
事件繫結 ( Event Binding )
這是我們目前網頁上的一張 Q 版的 chrome LOGO ,假設我們要在這張圖片加上 Click 點擊事件,點下去之後網站標題會跟著改變。
事件繫結語法 (一)
在事件中間加上 「-」,代表這是 Angular 的語法,並且在雙引號內放入 function ,但是在 Angular 內並沒有 function 只有類別,而類別內只有屬性以及方法。
template
1 | <img on-click="changeTitle()" [title]="title" [src]="imgUrl" [attr.data-title]="title" class="pull-left logo"> |
讓我們宣告一個方法叫做 changeTitle
。
component
1 | import { Component } from '@angular/core'; |
事件繫結語法 (二)
除了上述的作法外,也可以使用這種方式添加事件繫結。
template
1 | <img (click)="changeTitle()" [title]="title" [src]="imgUrl" [attr.data-title]="title" class="pull-left logo"> |
這樣的方式跟上一篇提到的屬性繫結是不是有點相似呢?
差別在於屬性繫結是使用中括號 [] 表示,而事件繫結是使用小括號 () 表示。
而大部分的 Angular 開發者都是使用第二種方法來進行事件綁定,較少使用第一種方法。
接著運行開發伺服器,測試看看結果。
標題的確被更新了,但這是怎麼辦到的呢?
事件繫結的背後
我們在 LOGO 上執行了 Click 動作,然後註冊 Angular 的事件繫結,而這個事件繫結到了 changeTitle
方法,因此當有人點了 LOGO 時,就會跳到 AppComponent 內去執行 changeTitle
方法。
而這個方法會藉由執行 this.title = 'changeTitle';
來變更 class 內的 title
屬性,又因為先前我們對網站標題使用了內嵌繫結,所以當 class 內的 title
屬性有異動時, Angular 就會管理頁面 DOM 的狀態,也就是所有頁面中有繫結 title
屬性的地方一起改變。
事件繫結 - 使用 $event 參數
當撰寫事件繫結時必須要傳入一個方法,預設可以不用傳入任何參數,但是在這裡確實可以傳入一個很特別的參數 $event
,讓我們觀察看看。
這個 $event
可以幫助我們取得事件的詳細資訊
template
1 | <img (click)="changeTitle($event)" [title]="title" [src]="imgUrl" [attr.data-title]="title" class="pull-left logo"> |
component
1 | import { Component } from '@angular/core'; |
接著運行開發伺服器,按下 F12 開啟開發者工具並點擊 LOGO 圖案。
可以看到跑出了很多東西,而這個 MouseEvent 其實就是 DOM 的 MouseEvent ,因此這一次觸發的滑鼠事件內可以找到相當多的屬性。
$event 參數內 - target
target
屬性代表的是剛剛點下去的那個 DOM 物件,例如說剛剛我們是點擊 img 觸發的,也就是說它的 target
屬性會是:
$event 參數內 - altkey
altkey
屬性代表的是點擊時有沒有按下 「alt」 這個按鍵,因此我們可以替剛剛那個範例加上一個新的需求,必須要按下 「alt」 這個按鍵才可以更改標題。
component
1 | import { Component } from '@angular/core'; |
我在這邊踩到了一的雷,那就是 altKey 的 K 是大寫,因此這部分要特別注意英文的大小寫部分。
搞定!運行開發伺服器測試看看
但是這個部分可以有更好的寫法,那就是使用具有型別的 $event 參數
事件繫結 - 使用具有型別 $event 參數
在上一個範例裡,因為英文的大小寫導致程式沒有按我們預期的跑,但我們現在是使用 TypeScript 進行開發,所以我們可以利用 TypeScript 帶來的好處,利用型別來標註參數的型別,具體來說我們可以這麼做:
- 由剛才範例可知
$event
的內容其實是 MouseEvent- 也就是說傳入方法的參數其實是 MouseEvent 的型別
因此可以在 Component 內這麼寫:
1 | import { Component } from '@angular/core'; |
接著神奇的事情發生了,當我們輸入 $event
並按下 .
時,VS Code 會列出所有 MouseEvent 內所有可以選擇的屬性。
巧妙的利用型別重構
我們知道可以在事件繫結中傳入 $event
參數,但其實這個部分可以更進一步的改寫,並且結合剛才的提到的型別,例如:
template
1 | <img (click)="changeTitle($event.altKey)" [title]="title" [src]="imgUrl" [attr.data-title]="title" class="pull-left logo"> |
可以直接在這個地方就傳入
$event.altKey
。
component
1 | import { Component } from '@angular/core'; |
然而因為 $event.altKey
的值是 true 或 false ,因此型別是布林。
接著可以再次確認運作是否正常。
小結
在事件繫結中,有些同樣的事情會有不同的方法可以實作,至於要用哪種方式撰寫就見仁見智了。對我來說,怎麼樣的寫法是易懂又容易維護的,那就是值得學習的好方法。