首页 > 解决方案 > mat-chip 未根据初始 FormControl 值呈现

问题描述

我需要使用 formControl 的值来渲染 mat-chips,并且还需要渲染多选选项。我也使用了材料模块。它不显示 formControl 的初始值

HTML:

<mat-form-field>
  <mat-label>Toppings</mat-label>
  <mat-select [formControl]="toppingsControl" multiple>

    <mat-select-trigger>
      <mat-chip-list>
        <mat-chip *ngFor="let topping of toppingsControl?.value"
          [removable]="true" (removed)="onToppingRemoved(topping)">
          {{ topping?.name }}
          <mat-icon matChipRemove>cancel</mat-icon> 
        </mat-chip> 
      </mat-chip-list> 
    </mat-select-trigger>

    <mat-option *ngFor="let topping of toppingList$ | async" [value]="topping">{{topping.name}}</mat-option>

  </mat-select>
</mat-form-field>

<br/>
{{ toppingsControl?.value | json }}

ts文件:

export class SelectMultipleExample {
  private test = new Subject<{ id: number; name: string }[]>();
  toppingList$ = this.test.asObservable();

  // Initialize formCOntrol value
  toppingsControl = new FormControl([{ id: 1, name: "Extra cheese" }]);

  constructor() {
    setTimeout(() => {
      this.test.next([
        { id: 1, name: "Extra cheese" },
        { id: 2, name: "Mushroom" }
      ]);
    }, 5000);
  }

  onToppingRemoved(topping: string) {
    const toppings = this.toppingsControl.value as string[];
    this.removeFirst(toppings, topping);
    this.toppingsControl.setValue(toppings); // To trigger change detection
  }

  private removeFirst<T>(array: T[], toRemove: T): void {
    const index = array.indexOf(toRemove);
    if (index !== -1) {
      array.splice(index, 1);
    }
  }
}

单击以查看屏幕上呈现的内容:

标签: angularangular-material

解决方案


我认为这是因为您使用了 { id: 1, name: "Extra cheese" } 的 2 个实例。

所以你必须做你想做的事:

  • 您使用对象的相同实例,如下所示:

myExtraCheeseObject = { id: 1, name: "Extra cheese" };
 
 // Initialize formControl value
  toppingsControl = new FormControl([myExtraCheeseObject]);

  constructor() {
    setTimeout(() => {
      this.test.next([
        myExtraCheeseObject,
        { id: 2, name: "Mushroom" }
      ]);
    }, 5000);
  }

// just compare ids
compareObjects(o1: any, o2: any) {
  return o1.id == o2.id
}

// compare id and name
compareObjects(o1: any, o2: any) {
  return o1.id == o2.id && o1.name == o2.name
}
 <mat-select [formControl]="toppingsControl" 
     [compareWith]="compareObjects"
     multiple>
 </mat-select>

(另一个提示:您应该避免在构造函数中使用 setTimeout 和代码,而是使用 ngOnInit)


推荐阅读