如何在 Angular 反应形式中使用完整对象

How to use full objects in Angular reactive forms

我正在更新一些旧的 angular 表单,并且在将表单设置为对象的整个实例的同时还能够设置初始值时遇到了问题。

我曾尝试将 [value]="option" 设置为整个对象,同时设置 {{ option.$type }} 但初始值未显示。我也尝试过使用 [ngValue] 但即使我导入 ReactiveFormModule

也会出现错误

当前代码:

<mat-form-field fxFlex="49">
    <mat-select placeholder="Type" formControlName="type" autocomplete="off" required>
        <mat-option *ngFor="let option of container$ | async" [value]="option.$type">{{ option.$type }}
        </mat-option>
    </mat-select>
</mat-form-field>

我希望将整个容器对象作为值,这样我以后就可以访问 option.$id,但是

this.editContainerForm.controls['type'].setValue(this.containerContext.$containerTypeName );

即使我用整个容器对象设置表单也会停止工作。

在这种情况下,对象通过引用进行比较,以便使用对象作为值必须是相同的引用

这意味着

const a = {type$ : 'A'};
const a2 = {type$:'A'}; 

console.log(a === a2); // false 

如果您尝试使用对象,两个对象必须是相同的引用

  const a = {type$ : 'A'};
  const a2 = a; 

  console.log(a === a2); // true

基本示例

  form:FormGroup;
  container$;

  data = [
      {$type:'A'},
      {$type:'B'},
      {$type:'C'},
    ]
  constructor(fb:FormBuilder) {
    this.form = fb.group({
      type:this.data[1]
    })

    this.container$ = of(this.data)
  }

如您所见,类型具有相同的引用值,请检查 stackblitz demo

已更新! ✨

您可以提供 [compareWith][2] 将选项值与选定值进行比较的函数。第一个参数是来自选项的值。第二个是来自选择的值。应返回一个布尔值。

  compareWith(value , selectedValue ) {
    return value.$type === selectedValue.$type
  }

模板

<mat-select placeholder="Type" formControlName="type" autocomplete="off" required [compareWith]="compareWith">
    <mat-option *ngFor="let option of container$ | async" [value]="option" >{{ option.$type }}
    </mat-option>
</mat-select>

stackblitz demo