如何从 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 进行查找更改或修改提交逻辑,就像亚历山大的回答说的那样。
我会把这个答案留在这里以防它对任何人有帮助,但我仍然对其他想法持开放态度。
我有一个 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 进行查找更改或修改提交逻辑,就像亚历山大的回答说的那样。
我会把这个答案留在这里以防它对任何人有帮助,但我仍然对其他想法持开放态度。