1. 程式人生 > 其它 >Angular10教程--2.3 雙向繫結

Angular10教程--2.3 雙向繫結

技術標籤:angular教程angulartypescript

Angular10教程--2.3 雙向繫結

前面我們瞭解了屬性繫結、事件繫結以及輸入和輸出的使用,是時候瞭解雙向綁定了。本節,我們將利用@Input()@Output()來了解下雙向繫結。
原文閱讀…

定義:雙向繫結為應用中的元件提供了一種共享資料的方式。使用雙向繫結繫結來偵聽事件並在父元件和子元件之間同步更新值。(其實,也就是對@Input()@Output()的一種簡化)

雙向繫結大致可以分成兩種型別:

一、普通元件的雙向繫結

這個型別的雙向繫結可以發生在任何元件任何DOM元素上,下面我們通過一個例項來具體認識一下。

src/app/components/下面建立一個sizer元件作為子元件:

// src/app/components/sizer/sizer.component.html
<div>
  <button class="btn btn-danger" (click)="dec()" title="smaller">-</button>
  <button class
="btn btn-primary" (click)="inc()" title="bigger">+</button> <label [style.font-size.px]="size">FontSize: {{size}}px</label> </div> // src/app/components/sizer/sizer.component.ts ... export class SizerComponent implements OnInit { public size =
14; // ... dec() { this.size++; } inc() { this.size--; } }

頁面將是這樣,且按鈕功能實現:

在這裡插入圖片描述
但是,這並不是我們想要的結果,我們需要從父元件傳入size,從而讓sizer元件改變字型大小。並且,通過sizer元件的按鈕點選事件,將改變後的size的值回傳給父元件。

接下來我們將使用前面的知識來改造程式碼(也就是雙向繫結的原理介紹):

// src/app/app.component.html
// 下面的$event就是子元件傳過來的值(必須是$event)
<app-sizer [size]="appFontSize" (onSizeChange)="appFontSize = $event"></app-sizer>
<div [style.font-size.px]="appFontSize">子元件修改後的FontSize: {{appFontSize}}</div>

// src/app/app.component.ts
...
export class AppComponent {
  appFontSize = 14;
}
// src/app/components/sizer/sizer.component.ts
...
export class SizerComponent implements OnInit {
  // 建立輸入屬性size,為number或字串型別
  @Input() size: number | string;
  // 建立自定義事件onSizeChange,需要一個number型別的引數
  @Output() onSizeChange = new EventEmitter<number>();
  ....
  dec() {
    this.resize(-1);
  }
  inc() {
    this.resize(1);
  }
  resize(step: number) {
    // 設定字型大小為12~40之間的值
    this.size = Math.min(40, Math.max(12, +this.size + step));
    // 通過事件傳值
    this.onSizeChange.emit(this.size);
  }
}

同樣實現了我們想要的效果:

在這裡插入圖片描述
但是,這樣是不是太麻煩了一點呢?下面,我們的雙向繫結正式出場:

Angular 的雙向繫結語法是方括號和圓括號的組合 [()][] 進行屬性繫結,() 進行事件繫結。修改下面程式碼:

// src/app/app.component.html
<app-sizer [(size)]="appFontSize"></app-sizer>
<div [style.font-size.px]="appFontSize">子元件修改後的FontSize: {{appFontSize}}</div>
// src/app/components/sizer/sizer.component.ts
...
export class SizerComponent implements OnInit {
  @Input() size: number | string;
  // 修改事件名,********必須是:屬性名 + Change 形式*********
  @Output() sizeChange = new EventEmitter<number>();
  ....
  resize(step: number) {
    this.size = Math.min(40, Math.max(12, +this.size + step));
    this.sizeChange.emit(this.size);
  }
}

會發現,功能沒有受影響。

二、表單中的雙向繫結[(ngModel)]

根據之前基本的雙向繫結知識,[(ngModel)]語法可拆解為:

1.名為ngModel的輸入屬性

2.名為ngModelChange的輸出屬性

單獨使用表單元素

首先需要引入FormsModule這個內建模組:

// src/app/app.module.ts 
import {FormsModule} from '@angular/forms';
...
@NgModule({
  // ...
  imports: [
    // ...
    FormsModule
  ],
  // ...
})

元件中使用:

<!-- src/app/app.component.html -->
<input type="text" [(ngModel)]="iptVal">
<p>input value is {{iptVal}}</p>

上面這行程式碼相當於:

<input [value]="iptVal" (input)="iptVal = $event.target.value" />

這其實很簡單的,類似vue裡面的寫法。

在標籤中使用

將程式碼放入<form>標籤內:

<!-- src/app/app.component.html -->
<form>
  <input type="text" [(ngModel)]="iptVal2">
  <p>form 中input value is {{iptVal2}}</p>
</form>

但是,我們會發現瀏覽器會報錯:

在這裡插入圖片描述
報錯意思說,在form表單中使用ngModel的話,我們需要給input新增一個name屬性或者設定[ngModelOptions]="{standalone: true}"

修改程式碼:

<!-- src/app/app.component.html -->
<form>
  <input type="text" [(ngModel)]="iptVal2" name="appIput2">
  <p>form 中input value is {{iptVal2}}</p>
</form>

或者:

<!-- src/app/app.component.html -->
<form>
  <input type="text" [(ngModel)]="iptVal2" [ngModelOptions]="{standalone: true}">
  <p>form 中input value is {{iptVal2}}</p>
</form

或者:

<!-- src/app/app.component.html -->
<form>
  <input type="text" [(ngModel)]="iptVal2" [ngModelOptions]="{name: 'appIput2'}">
  <p>form 中input value is {{iptVal2}}</p>
</form

在表單元素 中使用雙向繫結就是這麼簡單了,注意引入FormsModule模組就行。

總結:

1、雙向繫結的原理其實就是@Input()@Output()結合使用,需要注意語法是[(屬性名)]=“父元件中一個屬性名”,先繫結輸入,再繫結輸出;

2、在form表單中使用雙向繫結,應首先引入FormsModule這個內建模組,然後在input元素上新增name

歡迎關注我的公眾號,公眾號將第一時間更新angular教程:
在這裡插入圖片描述