Skip to content

Binding

可分為單向綁定及雙向綁定:

單向綁定:

> [ ]: 數據綁定,將 Component 中的屬性直綁定至 DOM 中,即數據的流向為 Component -> DOM。
需注意某些 Attribute 不會對應到 DOM Property,如:aria、svg 等 (1) > ( ): 事件綁定,監聽 DOM 的事件,並在事件發生時調用 Component 中的方法,即數據的流向為 DOM -> Component。
  1. ❌
    <svg width="{{100+100}}"></svg>
    
    ✅
    <svg [attr.width]="100+100"></svg>
    
[ ] 數據綁定
export class Page1Component {
    title = '屬性綁定';
    picURL = 'https://stickershop.line-scdn.net/stickershop/v1/product/24170521/LINEStorePC/main.png?v=1';
    isDisable = true;
}
<div style = "text-align: center">
    <h1>
        Welcome to {{title}}!
    </h1>
</div>
<img [src]="picURL" width="600" height="200" />
<br />

<button [disabled]="isDisable"> Save </button>
Result

binding[]

( ) 事件綁定
<div (click) = "onClick2($event, 'div')">
    <h3>$event</h3>
    <button (click) = "onClick2($event, 'button')">
        Button
    </button>
</div>

<div>
    你選的是:{{result}}
    <select (change) = "onchange($event)">
        <option value = "0101"> Java Script </option>
        <option value = "0102"> Type Script </option>
        <option value = "0103"> Angular </option>
    </select>
</div>
export class Page4Component {
    onClick2(event: Event, element: string) {
        console.log(element);
        console.log(event);
        console.log(event.target);
        console.log(event.currentTarget);
    };

    result: string = "";

    onchange(event: Event) {
        let selectElement: HTMLSelectElement = <HTMLSelectElement>event.target;
        console.log(selectElement.value);
        this.result = selectElement.value;
    }
}
Result

binding()

雙向綁定:

> [(ngModel)]: 用於 HTML 原生元素。

> @Input: 用於自訂屬性,Parent Component 傳遞數據予 Child Component 時使用,寫於 Child Component 中。

> @Output: 用於自訂屬性,Child Component 傳遞事件予 Parent Component 時,搭配 EventEmitter (1) 使用,寫於 Child Component 中。
  1. 定義事件的傳遞訊息型別,也就是 $event 的型別。
[(ngModel)]
export class AppComponent {
    title = '購物車';
    qty: number = 12;
    stock: number = 10;

    onCheck(qty_r: number, stock_r: number){
        this.qty = qty_r;
        this.stock = stock_r;
        console.log(this.qty > this.stock)
    };
}
<h1 #title1>
    {{title}}
</h1>

購買數量:<input type = "number" [(ngModel)]="qty"> <br/>
庫存數量:<input type = "number" [(ngModel)]="stock"><br/>
<button (click) = "onCheck(qty, stock)"> Check </button>
Result
  1. 載入 App ngModel

  2. 不更改數量和庫存,直接按 Check ngModel1

  3. 更改數量為 7,Check ngModel2

  4. 更改庫存為 5,Check ngModel3

@Input & @Output
import { Component, EventEmitter, Input, Output } from '@angular/core';

export class SearchBoxComponent {
    @Input() searchText: string = "";
    @Output() searchTextChange = new EventEmitter<string>();

    onSearch(search: string){
        this.searchText = search;
        console.log(this.searchText);
        this.searchTextChange.emit(this.searchText);
    }
}
<div>
    搜尋:<input type="text" #search [value] = "searchText">
    <button (click) = "onSearch(search.value)"> GO </button>
</div>
export class AppComponent {
    title = 'mod04';
    routeList = routes;
    mySearch: string = "";
    isTouch: boolean = false;
    isFound: boolean = false;
    resultStyles = {};
    onTextChange(search:string) {
        this.isTouch = true;
        this.isFound = search.length >3;
        this.resultStyles = {
        'border': this.isFound ? 'solid 3px blue' : 'solid 3px red',
        'color': this.isFound ? 'black' : 'red',
        'background-color': this.isFound ? 'yellow' : 'white'
        };
    }
}
<div style="text-align:center">
    <h1>
        Welcome to {{title}}
    </h1>
    <ul>
        <li *ngFor="let r of routeList">
        <a [routerLink]="[r.path]">{{r.title ? r.title : ""}}</a>
        </li>
    </ul>
</div>

<searchBox [(searchText)] = "mySearch" (searchTextChange)="onTextChange($event)"></searchBox>

<h3 [ngStyle] = "resultStyles" *ngIf = "isTouch">
    <ng-container *ngIf = "isFound; else notFound">
        找到了 {{mySearch}} !!
    </ng-container>
    <ng-template #notFound> 沒找到ㄋㄟ </ng-template>
</h3>
Result

in_output_1 in_output_2