# Angular - 事件綁定與雙向綁定 在前面的文章中有介紹了內嵌綁定與屬性綁定,在這篇文章將要介紹事件綁定與雙向綁定 ## 事件綁定與雙向綁定 ### 事件綁定 - Event Binding 不管在原生 JS 或是其他框架系統,事件綁定都是非常重要且必須好好學習的一個章節。不管是滑鼠點擊事件、畫面滾動事件,或是在送出表單的 submit 事件,這都是影響著整體網頁運作以及後續網頁運作的重要功成。 >**"Use () to bind from view to source"** - Angular 官方 在 Angular 中,進行事件綁定時,我們會需要使用到 `(事件)="eventHandler()"`,像是點擊事件就會寫成 `(click) = "handleClick()"` - 基礎事件綁定 ``` // 這是 app.component.html <div> <h1>{{ title }}</h1> <button (click)="hanldeClearTitle">clear</button> </div> // 這是 app.component.ts 文件 import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { title: string = 'title'; // 以下的 handleClearTitle 會在 click 事件時觸發 handleClearTitle() { this.title = ''; } } ``` 以上程式碼是使用點擊事件來清空 title ![](https://hackmd.io/_uploads/B1DvQa3N3.gif) - 將事件物件傳給 event handler 我們在撰寫事件綁定時,常常會使用到 `e.target` 或是 `e.key` 之類的語法,而其中的`e` 其實就是事件物件。 在 Angular 中,我們使用 `$event`,來將事件物件傳給處理該事件的handler。 ``` // 這是 app.component.html 文件 <div> <h1>{{ title }}</h1> <button (click)="handleClearTitle($event)">clear</button> </div> // 這是 app.component.ts 文件 export class AppComponent { title: string = 'title'; // 在處理事件的 handler 中取得 event 物件並且打印出來 handleClearTitle(event: Event) { console.log(event); this.title = ''; } } ``` 當你點擊按鈕,就會獲得到事件物件,並且被輸出在 console ![](https://hackmd.io/_uploads/rktb8p2Nn.png) ### 雙向綁定 - Two Way Biding 在 Angular 中,雙向綁定可以說是在建立表單時必要的基礎知識,有學過 React 的人一定了解,在進行表單驗證或是得到表單的資料時,都會需要使用許多的套件來進行,常常在獲取表單資料以及進行超多欄位驗證時感到心累,主要是因為 React 並沒有像 Angular 這樣的雙向綁定特性,而這也是 Angular 強大的一個地方。 在進行雙向綁定上時,會使用到 `[()]` (國外都稱他為香蕉盒子 banana box)。 >看見雙向綁定的符號可以發現,它其中同時帶了`屬性綁定[]` 與 `事件綁定()` 兩種方式成為雙向綁定。 > 從字面上來解釋也就是:當 component 或是 template 其中一方有改變,另一方也會產生改變! 在真正開始撰寫程式碼前,我們要先了解到第一個 `ng` 系列的用法,也就是 `ngModel`。 #### ngModel `ngModel` 是來自 Angular 中的 `@angular/forms` API 裡面的 `FormsModule`,它從域模型中創建一個FormControl實例,並將其綁定到表單控制元素上,這樣可以創造一個雙向綁定的資料流。 >**"Creates a FormControl instance from a domain model and binds it to a form control element."** - Angular 官方 首先,在使用`ngModle` 前,記得先到 `app.module.ts` 文件,輸入`import {FormsModule} from "@angular/forms"` 才有辦法使用 `ngModel`,因為 `ngModel` 是隸屬於FormsModule模組下的套件。 ``` // 這是 app.module.ts 文件 import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; // 新增這一行 import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], // 新增 FormsModule,才能使用 ngModel imports: [BrowserModule, AppRoutingModule, FormsModule], providers: [], bootstrap: [AppComponent], }) export class AppModule {} ``` #### 實作雙向綁定 以下程式碼將會結合 "**內嵌綁定**,**事件綁定**,**雙向綁定**" 來實作 ``` // 這是 app.component.html 文件 <div> <input type="text" [(ngModel)]="title" /> <h1>{{ title }}</h1> <button (click)="handleClearTitle($event)">clear</button> </div> // 這是 app.component.ts 文件 import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { title: string = 'title'; // 以下的 handleClearTitle 會在 click 事件時觸發 handleClearTitle(event: Event) { console.log(event); this.title = ''; } } ``` ![](https://hackmd.io/_uploads/SyPRqlaNh.gif) 上方就實作出了一個簡單的雙向綁定案例,並且在進行點擊事件時,也可以同時清空 title 的值,進而連帶影響內嵌綁定所呈現的畫面。 ## 補充:範本參考變數 Template Reference Variable 所謂的範本參考變數,指的是可以讓你在 template 的任意一處使用被標記過的 HTML 元件的數據。 要去宣告一個範本參考變數時,必需要使用 `#變數名稱` 來宣告。 注意,範本參考變數必須是唯一,且不可以跟變數名稱相同! ![範本參考變數](https://hackmd.io/_uploads/SyBsB-043.png) 以上範例可以藉由宣告一個範本參考變數,來讓下方的 `<p>` tag 獲得 `#tTaskInput` 的值。 (根據保哥的建議,可以在宣告範本參考變數時在前方加入一個 `t` 字來作為命名規則) ### 參考資料 - [# Day10 Angular牙起來 - 程式面介紹 繫結綁定4 雙向繫結](https://ithelp.ithome.com.tw/articles/10298582) - [Angular NgModel的完整指南](https://juejin.cn/post/7115245216969261092) - [Angular 基礎|從 Todo List 認識四種資料綁定](https://hackmd.io/@Heidi-Liu/angular-data-binding) ###### tags: `Angular`