[從 0 開始的 Angular 生活]No.17 資料繫結的四種方法 - 雙向繫結

前言

終於來到資料繫結的第四種方法 - 雙向繫結 ( Two-way Binding ) 了,而這種繫結方式跟其他三種有何不同呢?

雙向繫結 ( Two-way Binding )

到目前為止介紹了三種資料繫結的方法,分別是內嵌繫結、屬性繫結、事件繫結,這三種的前兩種都是屬於從 Component 單向將資料傳送到 Template 的繫結方式。而事件繫結也算是單向的繫結方式,這是從 Template 內透過瀏覽器的事件觸發之後呼叫 Component 內的方法。

而我們這次要介紹的繫結方式就是雙向的繫結方式,這種繫結方式會自動的做到屬性繫結與事件繫結,也因此我們寫的程式碼會更少、更精簡。

拿上一篇的練習改寫,使其具有雙向繫結效果

我們將之前的練習改寫,見識見識雙向繫結的威力。

template

1
2
3
4
5
6
7
8
9
10
<div class="widget-content">
<div id="searchbox">
<input type="text" placeholder="請輸入搜尋關鍵字" accesskey="s"
[(ngModel)]="inputValue"
(input)="calcLength($event.target.value)"
(keydown.escape)="cleanInput($event.target)">
<input type="button" value="搜尋" id="searchbutton">
</div>
目前字數 <span>{{inputStrLen}}</span>
</div>

要使用雙向繫結的話辦法相當簡單,使用 [(ngModel)] 語法後面接一個想要雙向繫結並且在 component 內的屬性即可。

component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'firstAngular';
link = 'http://www.google.com';
imgUrl = '/assets/images/logo.png';
inputValue = '';
inputStrLen = 0;
changeTitle(altKey: boolean) {
if (altKey) {
this.title = 'changeTitle';
}
}
calcLength(str: string) {
this.inputStrLen = str.length;
}
cleanInput(inputEl: HTMLInputElement) {
this.inputStrLen = 0;
inputEl.value = '';
}
}

當運行開發伺服器後會發現, Angular 又掛掉了。

意思就是 Angular 看不懂 ngModel 這個屬性是什麼。

也就是說如果我們想要使用雙向繫結,還有一個步驟要做,那就是把 Angular 表單的模組匯入到 AppModule 內。

於是打開 AppModule 這支檔案進行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

修改完成後,再次運行開發伺服器,發現可以成功運行網頁了,但我們還需要調整程式碼的部分。

可以透過內嵌繫結,測試一下剛才設置的雙向繫結 inputValue 有沒有成功

template

1
2
3
4
5
6
7
8
9
10
<div class="widget-content">
<div id="searchbox">
<input type="text" placeholder="請輸入搜尋關鍵字" accesskey="s"
[(ngModel)]="inputValue"
(input)="calcLength($event.target.value)"
(keydown.escape)="cleanInput($event.target)">
<input type="button" value="搜尋" id="searchbutton">
</div>
輸入文字:{{inputValue}} 目前字數 <span>{{inputStrLen}}</span>
</div>

藉由這個測試知道,目前這個 input 的輸入框跟 component 內的 inputValue 已經建立了雙向繫結。

完成這個練習

我們已經成功地建立了雙向繫結,接著把其他地方的程式碼也修改一下吧。

template

1
2
3
4
5
6
7
8
9
<div class="widget-content">
<div id="searchbox">
<input type="text" placeholder="請輸入搜尋關鍵字" accesskey="s"
[(ngModel)]="inputValue"
(keydown.escape)="cleanInput()">
<input type="button" value="搜尋" id="searchbutton">
</div>
輸入文字:{{inputValue}} 目前字數 <span>{{inputValue.length}}</span>
</div>

component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'firstAngular';
link = 'http://www.google.com';
imgUrl = '/assets/images/logo.png';
inputValue = '';
changeTitle(altKey: boolean) {
if (altKey) {
this.title = 'changeTitle';
}
}
cleanInput() {
this.inputValue = '';
}
}

搞定!最後運行開發伺服器,測試功能是否仍然正常。

雙向繫結不是萬靈丹

雙向繫結既然這麼好用,我們是不是應該不管怎麼樣都使用雙向繫結呢?

事實上,過度濫用雙向繫結也會給網頁效能造成一些負擔,可能導致網頁的反應會變慢,但具體來說還是得看實際狀況而定就是了。

小結

到這裡我們已經學會了 Angular 內四種資料繫結的方式了,接下來要介紹的是範本參考變數。

0%