Angular:与 mat-select 的双向绑定不起作用,在代码中赋值会导致它在 UI 中重置

Angular: 2-way binding with mat-select not working, assigning value in code causes it to reset in 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 没有正确显示它,但该值已正确分配。

您的代码中存在类型不匹配问题。

selectedType 的类型 Type 是一个数字。

您在

中设置 [value]="type.key" 的位置

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

type.key 是一个字符串,由于 keyvalue 管道。

在上面的代码中,当您 select 将下拉列表中的一项作为字符串值“0”或“1”分配给 selectedType 时。如果您以编程方式分配一个值,例如 this.selectedType = Type.Hardware,则数字值 0 将分配给 selectedType

并且由于您的 compareType 函数使用 strict equality (===) 它 returns false 因为 1 === "1"false

你也可以;

  • 使您的 enum Type 具有字符串值;
enum Type {
  Hardware = "0",
  Software = "1"
}
  • 或者,在绑定到 mat-option
  • 时将 type.key 转换为数字
[value]="+type.key"
  • 或者,在 compareType 函数中使用 equality (==) 而不是 strict equality (===)。 (我个人不推荐这个!)
  compareType(type1: Type, type2: Type): boolean {
    return ((type1 as Type) == (type2 as Type));
  }

这是一个有效的 demo