網站搜尋

typescript - Angular:mat-select 的雙向綁定無法正常工作,在程式碼中分配值會導致 UI 重置


我正在嘗試將 mat-select 綁定到像這樣的列舉值:

<mat-form-field>
  <mat-label>Type</mat-label>
  <mat-select [(ngModel)]="selectedType" [compareWith]="compareType">
    <mat-select-trigger>
      {{types[selectedType]?.name}}
    </mat-select-trigger>
    <mat-option *ngFor="let type of types | keyvalue" [value]="type.key">
      <mat-icon>{{type.value.icon}}</mat-icon> {{type.value.name}}
    </mat-option>
  </mat-select>
</mat-form-field>

以及這個打字稿:

enum Type {
  Hardware = 0,
  Software = 1
}

types: { [TP in number]: { icon: string, name: string }; } = {
  [Type.Hardware]: { icon: 'computer', name: 'Hardware' },
  [Type.Software]: { icon: 'keyboard', name: 'Software' },
};

selectedType: Type;

compareType(type1: Type, type2: Type): boolean {
  return ((type1 as Type) === (type2 as Type));
}

我希望 select 的值能綁定到 selectedType,我正在嘗試使用 [(ngModel)]="selectedType" [compareWith]="compareType" 來實現這個目的。

問題是,這個資料綁定並沒有完全雙向運作。當我使用 UI 指派一個值時,綁定會相應更新,但當我在程式碼中更新值時,它會重設 UI 中的值,再次顯示佔位符。然而,雖然 UI 沒有正確顯示,但值已正確指派。

答案#1

你的程式碼中有類型不匹配的問題。

selectedType 的類型是 Type,它是一個數字。

在其中你設置[value]="type.key"的位置

<mat-option *ngFor="let type of types | keyvalue" [value]="type.key">

type.key 是字串,因為使用了 keyvalue 管道。

在上面的程式碼中,當你從下拉選單中選擇一個項目時,字串值 "0" 或 "1" 會被指派給 selectedType。如果你像這樣程式化地指派一個值 this.selectedType=Type.Hardware,數值 0 會被指派給 selectedType。

由於你的 compareType 函數使用嚴格相等(===),它返回 false,因為 1 === "1" 為 false

你可以選擇其中一個;

  • 讓你的 enum Type 擁有字串值;
enum Type {
  Hardware = "0",
  Software = "1"
}
  • 或者,在綁定到 mat-option 時,將 type.key 轉換為數字
[value]="+type.key"
  • 或者,在 compareType 函數中使用相等 (==) 代替嚴格相等 (===)。(我個人不推薦這個!)
  compareType(type1: Type, type2: Type): boolean {
    return ((type1 as Type) == (type2 as Type));
  }

這裡有一個可運作的示範