问题描述
我正在尝试根据具有填充内容的初始数据从组中创建动态对象,并从组中添加/删除。不幸的是,它无法正常工作。
预期的行为是
- Coutry下拉菜单将加载数据,并以选定的值突出显示,这已经可以正常工作了。
- 默认情况下,应使用从初始数据
stateCode
中选择的值来加载“选择的国家/地区”下拉数据,并且在更改当前也不可用的国家/地区时。 - 在单击添加按钮时,默认情况下应加载“美国”国家/地区和相应州的数据。默认情况下,“状态”下拉列表应使用“ --select--”进行选择。
注意:所有数据将来自API。为了测试目的,我为国家和州添加了静态对象。
这是我的尝试
https://stackblitz.com/edit/angular-8-app-example-fkjzfe-wekubn?file=src%2Fapp%2Fapp.component.ts
当前行为演示
https://angular-8-app-example-fkjzfe.stackblitz.io/
HTML
<form [formGroup]='entityForm'>
<div formArrayName="optionGroups" class="ui-g ui-g-12 ui-g-nopad " >
<div style="width: 100%;
display: flex; margin-bottom:10px" class="ui-g ui-g-12 ui-g-nopad " *ngFor="let item of entityForm.controls['optionGroups'].controls; let $index=index" [formGroup]="item">
<div class="ui-md-4">
<label class="mandatory"
>Country
<span class="colon"></span>
</label>
<select formControlName="country" class="ui-inputtext" (change)="onCountryChange(entityForm.controls['optionGroups'].controls[$index].controls['country'].value,$index)" >
<option>--Select--</option>
<option *ngFor="let c of countries" [ngValue]="c.countryCode">{{c.country}}</option>
</select>
</div>
<div class="ui-md-4">
<label class="lbl-hidden"> State </label>
<select formControlName="state" class="ui-inputtext">
<option>--Select--</option>
<option *ngFor="let state of states[entityForm.controls['optionGroups'].controls[$index].controls['country'].value]" value="state.code">{{state.state}}</option>
</select>
</div>
<div class="ui-md-3">
<label class="lbl-hidden"> Number </label>
<input
type="text"
pInputText
class="form-control"
formControlName="place"
/>
</div>
<div class="ui-md-1">
<button (click)='removeOptionGroup(i)' style="min-width: auto;" pButton icon="fa fa-minus">Remove</button>
</div>
</div>
</div>
</form>
<button class="add-remove-btn" pButton (click)='addOptionGroup()' icon="fa fa-plus">Add</button>`
TS
import { Component,OnInit,ViewChild } from '@angular/core'
import { FormBuilder,Validators,FormArray,FormGroup,FormControl } from '@angular/forms';
@Component({
selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
public countryOptions:any = [];
public stateOptions:any = [];
public countries = [];
public states = [];
public entityForm: FormGroup;
constructor(private fb: FormBuilder) {
this.entityForm = this.fb.group({
optionGroups : this.fb.array([]),});
this.countries = this.countryOptions
this.states=[];
}
public addOptionGroup(){
const fa = this.entityForm.controls["optionGroups"] as FormArray;
//fa.setValue("--Select--");
fa.push(this.newOptionGroup());
}
public removeOptionGroup(index: number){
const fa = this.entityForm.controls["optionGroups"] as FormArray;
fa.removeAt(index);
}
onCountryChange(selectedCountry: string,formIndex : number) : void {
this.states[selectedCountry] = this.getStates(selectedCountry)
}
private newOptionGroup() {
return new FormGroup({
country: new FormControl("--select--"),state: new FormControl("--select--"),place: new FormControl("GGG"),});
}
getStates(selectedCountry) {
//API call
switch(selectedCountry) {
case "US" :
this.stateOptions =[
{id: 14,state: "Alabama",code: "AL",countryCode: "US"},{id: 15,state: "Alaska",code: "AK",{id: 17,state: "Arizona",code: "AZ",{id: 18,state: "Arkansas",code: "AR",{id: 19,state: "California",code: "CA",countryCode: "US"}
]
break;
case "CA" :
this.stateOptions =[{id: 37,state: "Marshall Islands",code: "MH",countryCode: "CA"},{id: 4,state: "New Brunswick",code: "NB",{id: 5,state: "Newfoundland and Labrador",code: "NL",{id: 53,state: "northern Mariana Islands",code: "MP",{id: 6,state: "northwest Territories",code: "NT",countryCode: "CA"}]
break;
default:
this.stateOptions =[
{id: 14,countryCode: "US"}
]
break;
}
return this.stateOptions;
}
initFormArray(initForm:any) {
const formArray = this.entityForm.get('optionGroups') as FormArray;
initForm.map((item,index) => {
formArray.push(this.createForms(item,index));
});
this.entityForm.setControl('optionGroups',formArray);
}
createForms(adresse,index): FormGroup {
let formGroup: FormGroup = new FormGroup(
{
country: new FormControl(adresse.countryCode),state: new FormControl(adresse.stateCode),place: new FormControl(adresse.fileNumber)
}
);
this.onCountryChange(adresse.select1,index)
return formGroup;
}
getAllCountries() {
//API call
this.countries = [{"country":"United States","countryCode":"US"},{"country":"Canada","countryCode":"CA"}]
}
ngOnInit() {
this.getAllCountries()
const initData = [
{countryCode: "US",stateCode: "AZ",fileNumber: "AAA"},{countryCode: "CA",stateCode: null,fileNumber: null}
]
this.initFormArray(initData)
}
}
解决方法
我简化了您的脚本,似乎可以正常工作。但这还没有结束-可能会做得更漂亮。请注意html的组成部分-[formGroupName] =“ i”以及如何使用formArray变量。
//html
<form [formGroup]="entityForm">
<div formArrayName="optionGroups" class="ui-g ui-g-12 ui-g-nopad">
<ng-container *ngFor="let item of optionGroups.controls; let i = index;" [formGroupName]="i">
<div style="width: 100%; display: flex; margin-bottom:10px" class="ui-g ui-g-12 ui-g-nopad">
<div class="ui-md-4">
<label class="mandatory">Country <span class="colon"></span></label>
<select
formControlName="country"
class="ui-inputtext"
(change)="onCountryChange(item.get('country').value,i)"
>
<option>--Select--</option>
<option *ngFor="let c of countries" [ngValue]="c.countryCode">{{c.country}}</option>
</select>
</div>
<div class="ui-md-4">
<label class="lbl-hidden"> State </label>
<select formControlName="state" class="ui-inputtext">
<option>--Select--</option>
<option *ngFor="let state of getStates(item.controls['country'].value)" [ngValue]="state.code">{{state.state}}</option>
</select>
</div>
<div class="ui-md-3">
<label class="lbl-hidden"> Number </label>
<input
type="text"
pInputText
class="form-control"
formControlName="place"
/>
</div>
<div class="ui-md-1">
<button (click)='removeOptionGroup(i)' style="min-width: auto;" pButton icon="fa fa-minus">Remove</button>
</div>
</div>
</ng-container>
</div>
</form>
<button class="add-remove-btn" pButton (click)='addOptionGroup()' icon="fa fa-plus">Add</button>
//ts
public countryOptions:any = [];
public stateOptions:any = [];
public countries = [];
public states = [];
public entityForm: FormGroup;
public optionGroups: FormArray;
constructor(
private fb: FormBuilder
) {}
ngOnInit() {
this.entityForm = this.fb.group({
optionGroups : this.fb.array([])
});
this.optionGroups = this.entityForm.get('optionGroups') as FormArray;
this.getAllCountries();
const initData = [
{countryCode: "US",stateCode: "AZ",fileNumber: "AAA"},{countryCode: "CA",stateCode: null,fileNumber: null}
]
this.initFormArray(initData)
}
public addOptionGroup(){
const fa = this.entityForm.get('optionGroups') as FormArray;
//fa.setValue("--Select--");
fa.push(this.newOptionGroup());
}
public removeOptionGroup(index: number){
const fa = this.entityForm.controls["optionGroups"] as FormArray;
fa.removeAt(index);
}
onCountryChange(selectedCountry: string,formIndex : number) : void {
console.log(selectedCountry);
this.states[selectedCountry] = this.getStates(selectedCountry)
}
private newOptionGroup() {
return new FormGroup({
country: new FormControl("--select--"),state: new FormControl("--select--"),place: new FormControl("GGG"),});
}
getStates(selectedCountry) {
//API call
switch(selectedCountry) {
case "US" :
this.stateOptions =[
{id: 14,state: "Alabama",code: "AL",countryCode: "US"},{id: 15,state: "Alaska",code: "AK",{id: 17,state: "Arizona",code: "AZ",{id: 18,state: "Arkansas",code: "AR",{id: 19,state: "California",code: "CA",countryCode: "US"}
]
break;
case "CA" :
this.stateOptions =[{id: 37,state: "Marshall Islands",code: "MH",countryCode: "CA"},{id: 4,state: "New Brunswick",code: "NB",{id: 5,state: "Newfoundland and Labrador",code: "NL",{id: 53,state: "Northern Mariana Islands",code: "MP",{id: 6,state: "Northwest Territories",code: "NT",countryCode: "CA"}]
break;
default:
this.stateOptions =[
{id: 14,countryCode: "US"}
]
break;
}
return this.stateOptions;
}
initFormArray(initForm:any) {
console.log(initForm);
initForm.map((item,index) => {
this.optionGroups.push(this.createForms(item,index));
});
}
createForms(adresse,index): FormGroup {
const formGroup = new FormGroup({
country: new FormControl(adresse.countryCode),state: new FormControl(adresse.stateCode),place: new FormControl(adresse.fileNumber)
});
this.onCountryChange(adresse.select1,index);
return formGroup;
}
getAllCountries() {
//API call
this.countries = [{"country":"United States","countryCode":"US"},{"country":"Canada","countryCode":"CA"}]
}