为什么我不能在反应式表单中使用带有基于对象的选项的选定元素?我做错了什么?



我有一个反应式表单,其中包括一个父表单(国家(和一个子表单数组(stateForm(,其中包含一个具有基于对象的选项的选择元素。我正在使用 [ngValue] 将选择元素的值设置为对象。使用选择列表的"(更改("事件时,我无法从表单控件中检索所选值。

我从一个更复杂的页面中缩减了这个例子。所以,我知道可能还有其他方法可以完成,但我有兴趣弄清楚为什么我无法获得基于对象的选择选项来使用此设置。

这是演示该问题的堆栈闪电战的链接: https://stackblitz.com/edit/angular-jigxyl

以下是堆栈闪电战代码的相关部分

ngOnInit(): void {
this.getCountry().subscribe(
country => {
this.country = country;
this.countryForm = this.buildFormGroup();
},
(error: any) => {
console.log(error);
}
);
}
CityCompare(c1: City, c2: City): boolean {
return c1 && c2 ? c1.name === c2.name : c1 === c2;
}
onSelectedStateChange(index: any): void {
var rowsFormArray = <FormArray>this.countryForm.controls["statesForm"];
var formGroup = <FormGroup>rowsFormArray.controls[index];
this.selectedCity = formGroup.controls["selectedCity"].value;
console.log(this.selectedCity);
}
private buildFormGroup(): FormGroup {
var formArray = new FormArray([]);
for (let i = 0; i < this.country.states.length; i++) {
var state = this.country.states[i];
var formGroup = new FormGroup({});
var formControl = new FormControl(state.selectedCity, [Validators.required]);
formGroup.addControl("selectedCity", formControl);
formArray.push(formGroup);
}
return new FormGroup({
statesForm: formArray
});
}
<form [formGroup]="countryForm">
<div>
<p>
I am using reactive forms and trying to use objects to set the options list
of a select element
<br/>
This form containts a form array as well. 
<br/>
No matter which option I choose, the form control always evaluates to the first options<br/>
--------------------------------------
</p>
</div>
<div>
Country:{{country?.name}}
</div>
<div formArrayName="statesForm">
<div *ngFor="let state of country?.states; let $index = index">
<div>State: {{state.abbreviation}}</div>
<div [formGroupName]="$index">
<select
class="form-control input-sm"
formControlName="selectedCity"
[compareWith]="CityCompare"
(change)="onSelectedStateChange($index)"
>
<option *ngFor="let city of state?.cities" [ngValue]="state?.selectedCity">
{{ city?.name }}
</option>
</select>
</div>
</div>
</div>
Chosen object:{{this.selectedCity | json}}
</form>

你只需要将ngValue设置为城市对象,所选值alreay设置你可以检查

<div formArrayName="statesForm">
<div *ngFor="let state of country?.states; let $index = index">
<div>State: {{state.abbreviation}}</div>
<div [formGroupName]="$index">
<select
class="form-control input-sm"
formControlName="selectedCity"
[compareWith]="CityCompare"
(change)="onSelectedStateChange($index)">
<option *ngFor="let city of state?.cities" [ngValue]="city">
{{ city?.name }}
</option>
</select>
</div>
</div>
</div>

演示 🔥🔥

您无需跟踪表单已经同步的选定值 与 UI 一起,因此任何更改都将反映到表单组

getSelectedStateValue(index) {
return (this.countryForm.get('statesForm') as FormArray).controls[index].value
}

模板

Chosen object:{{getSelectedStateValue($index) | json}}

(change)事件是一个模板驱动的表单方法,您希望在使用 reative 表单时订阅表单控件上的 valueChanges:

this.countryForm.get('statesForm').valueChanges.subscribe(v => 
this.onSelectedStateChange(v[0]));

闪电战:https://stackblitz.com/edit/angular-pxxuxy?file=src/app/app.component.ts

这种情况有点奇怪,BC 你有一个带有控件的数组的组,但只有一个选定的城市,而似乎可能有多个城市。

由于某种原因,您还将每个选项的值设置为该州的所选城市,您需要将选项值设置为每个城市:

[ngValue]="city"

最新更新