Try   HackMD

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

  • 將事件物件傳給 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

雙向綁定 - 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 = '';
  }
}


上方就實作出了一個簡單的雙向綁定案例,並且在進行點擊事件時,也可以同時清空 title 的值,進而連帶影響內嵌綁定所呈現的畫面。

補充:範本參考變數 Template Reference Variable

所謂的範本參考變數,指的是可以讓你在 template 的任意一處使用被標記過的 HTML 元件的數據。
要去宣告一個範本參考變數時,必需要使用 #變數名稱 來宣告。
注意,範本參考變數必須是唯一,且不可以跟變數名稱相同!

範本參考變數

以上範例可以藉由宣告一個範本參考變數,來讓下方的 <p> tag 獲得 #tTaskInput 的值。
(根據保哥的建議,可以在宣告範本參考變數時在前方加入一個 t 字來作為命名規則)

參考資料

tags: Angular