角材料-直接将对象传递给FormControl

时间:2019-03-27 12:42:50

标签: angular angular-material

我遇到了Angular Material中的一个问题,如果您直接将对象直接传递给 FormControl <mat-select>值>。

app.component.html

<!-- NOTE: The only difference is in [formControl] value -->

<!-- This example works well because I'm using 'toppings' form control -->
<mat-form-field>
  <mat-label>Toppings</mat-label>
  <mat-select [formControl]="toppings">
    <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping.name}}</mat-option>
  </mat-select>
</mat-form-field>

<!-- This is where it fails, no value is preselected -->
<mat-form-field>
  <mat-label>Toppings 2</mat-label>
  <mat-select [formControl]="toppings2">
    <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping.name}}</mat-option>
  </mat-select>
</mat-form-field>

app.component.ts

  toppingList: any[] = [
    {id: 42, name: "Item3123"},
    {id: 45, name: "Item444"},
    {id: 426, name: "Iteml"},
  ]
  toppings = new FormControl(this.toppingList[0]);
  toppings2 = new FormControl({id: 42, name: "Item3123"});

您可以看到toppings和toppings2之间的区别是我传递对象的方式。最后,对象是完全相同的。我尝试不使用Angular Material(使用常规<select>)做同样的事情,并且效果很好。

StackBlitz Link

有人对这种行为有解释吗?

1 个答案:

答案 0 :(得分:1)

解释可以在JB Nizet对您的问题的第一条评论中找到-它们不是同一对象(它们只是具有相同的ID和名称),因此是普通比较,例如==或{{1 }}失败。用于确定是否选择列表项的default compare function in MatSelect是:

===

解决方案是使用private _compareWith = (o1: any, o2: any) => o1 === o2; 功能替代您自己的比较功能:

compareWith

进一步阅读: http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html