angular - 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);
}
}
}
解决方案
我认为这是因为您使用了 { 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);
}
- 你使用
compareWith
(https://material.angular.io/components/select/api)
// 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)