Material Autocomplete 教學 - slioplark/angular-tutorial GitHub Wiki

一般的 autocomplete

使用 matAutocomplete 屬性建立 template variable ( #auto ),以連結 mat-autocomplete 標籤,使 input 標籤可取得 user$ 資料。

<mat-form-field>
    <input type="text" matInput [matAutocomplete]="auto">
    <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayUserFn">
        <mat-option *ngFor="let item of users$ | async" [value]="item">
            {{ item }}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>

具有 filter 的 autocomplete

1. 建立 formGroup 與 formControlName

<section [formGroup]="form">
    <input type="text" formControlName="user">
</section>

2. 利用 formBuilder 針對表單的 formControlName 建立關係

constructor(
    private formBuilder: FormBuilder
) { }

form = this.formBuilder.group({
    user: [null]
});

3. 監聽 value change 事件,並針對 value 進行 filter 功能

this.form.get('user').valueChanges.pipe(
    map(value => result.filter(item => 
        item.toLowerCase().includes(value.toLowerCase())
    )
);

設定 display value 的 autocomplete

1. 使用 displayWith 屬性,設定需呈現的 value

若 value 屬性綁定的 item 是一個 object 型別,則頁面上呈現的資料會以 { } 格式顯示,為了希望以 string 型別出現在 input 上,則需使用 displayWith 屬性以設定顯示在頁面上的 value。

<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayUserFn">
    <mat-option *ngFor="let item of users$ | async" [value]="item">
        {{ item.name }}
    </mat-option>
</mat-autocomplete>

2. 新增 displayUserFn 方法

displayUserFn(item) {
    return item ? item.name : undefined;
}

3. 針對 filter 進行例外處理

在 filter 前,需判斷 value 的型別是否為 string,否則後面無法對非 string 的變數進行 toLowerCase() 以發生無法預期的錯誤。

由於 autocomplete value 現在綁定的是 object,因此很有可能傳進一個非 string 的 value

this.form.get('user').valueChanges.pipe(
    map(value => typeof value === 'string' ? value : value.name),
    map(value => result.filter(item => 
        item.toLowerCase().includes(value.toLowerCase())
    )
);
⚠️ **GitHub.com Fallback** ⚠️