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

时间:2018-11-14 17:25:15

标签: javascript angular angular-reactive-forms

我有一个选择字段,可让我选择汽车,汽车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 => { ... );

我可以更改选择字段以绑定对象,而不是像这样绑定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。

是否有一种优雅的方法来获取所选对象,但仍将ID绑定到表单?

2 个答案:

答案 0 :(得分:1)

您拥有carId,因此只需在valueChanges的cars数组中查找car对象。

更改汽车价值而不是ID并更改提交逻辑要容易得多。

答案 1 :(得分:0)

这有点笨拙,但是我找到了一种可以忍受的方式。我将选择字段绑定到独立的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>

更新我对此解决方案仍然不满意,因为我还必须确保在调用carform.setValue()选择是同步的,这意味着我必须从其ID查找汽车-因此,我也可以像选择亚历山大(Alexander)的答案那样对选择的更改进行查找或修改提交逻辑。

我将在此处保留此答案,以防它对任何人都有帮助,但我仍然愿意接受其他想法。