如何从 valueChanges 中获取选定的对象,但仅将对象 ID 绑定到使用 Angular 反应形式的形式?

How to get selected object from valueChanges but only bind object id to form using Angular reactive forms?

我有一个 select 字段,允许我选择汽车并且汽车 ID 绑定到表单。

<mat-form-field>
  <mat-label>Car</mat-label>
  <mat-select formControlName="carId">
    <mat-option *ngFor="let car of cars | async" [value]="car.carId">
      {{car.carName}}
    </mat-option>
  </mat-select>
</mat-form-field>

我想获取汽车的实例,以便我可以从对象中获取其他信息,但我不能使用 valueChanges 来做到这一点,因为它只给我 ID:

this.form.get('carId').valueChanges.subscribe(carId => { ... );

我可以更改 select 字段来绑定对象而不是 id,如下所示:

<mat-form-field>
  <mat-label>Car</mat-label>
  <mat-select formControlName="carId">
    <mat-option *ngFor="let car of cars | async" [value]="car">
      {{car.carName}}
    </mat-option>
  </mat-select>
</mat-form-field>

但是整个对象都被绑定到表单,而不仅仅是 id,这会弄乱我的表单提交。

有没有一种优雅的方法来获取 selected 对象,但仍然只将 id 绑定到表单?

您有 carId,因此只需在 valueChanges 的汽车数组中查找汽车对象。

虽然更改为汽车值而不是 id 并更改您的提交逻辑要容易得多。

它有点笨拙,但我找到了一种我可以接受的方式。我将 select 字段绑定到独立的 FormControl,因此使用 [formControl]= 而不是 formControlName=

对其进行更改不会影响表单
<mat-form-field>
  <mat-label>Car</mat-label>
  <mat-select [formControl]="car">
    <mat-option *ngFor="let car of cars | async" [value]="car">
      {{car.carName}}
    </mat-option>
  </mat-select>
</mat-form-field>

然后我可以订阅更改,对汽车进行我需要的操作,并在表单上设置 carId。

this.car = new FormControl([null, Validators.required]);
this.car.valueChanges.subscribe(selectedCar => {
  // Do whatever with selectedCar here
  this.form.get('carId').setValue(selectedCar ? selectedCar.carId : null);
});

这行得通,但为了使其与 Angular Material 错误处理一起工作(因此如果未指定,该字段将变为红色)我必须添加绑定到 carId 的隐藏输入。

<mat-form-field>
  <mat-label>Car</mat-label>
  <input matInput formControlName="carId" style="display:none">
  <mat-select [formControl]="car">
    <mat-option></mat-option>
    <mat-option *ngFor="let car of cars | async" [value]="car">
      {{car.carName}}
    </mat-option>
  </mat-select>
  <mat-error *ngIf="form.get('carId').hasError('required')">
    Car is required
  </mat-error>
</mat-form-field>

更新 我仍然对这个解决方案不满意,因为我还必须确保 car select 在 form.setValue() 被调用,这意味着我必须从它的 id 中查找汽车 - 所以我不妨对 select 进行查找更改或修改提交逻辑,就像亚历山大的回答说的那样。

我会把这个答案留在这里以防它对任何人有帮助,但我仍然对其他想法持开放态度。