我有一个包含字符串数组的表单,每当我向列表中添加一个元素时,问题是当我使用setValue在数组中设置值时,它会显示以下错误
<button (click)="addNewCompany()">Add new Company</button><br><br>
<form [formGroup]="myForm">
<div formArrayName="companies">
<div *ngFor="let comp of getForm(); let i=index>
<fieldset>
<legend>
<h3>COMPANY {{i+1}}: </h3>
</legend>
<label>Company Name: </label>
<input [formControlName]="i" /><span><button (click)="deleteCompany(i)">Delete Company</button></span>
</fieldset>
</div>
</div><br>
</form>
export class AppComponent implements OnInit {
@Input()
public product: Product;
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
companies: this.fb.array([])
});
}
ngOnInit() {
this.addNewCompany();
this.myForm.controls['companies'].setValue(this.product.companies); // error
}
getForm(): any {
return this.myForm.get("companies")["controls"];
}
addNewCompany() {
const control = <FormArray>this.myForm.get("companies");
control.push(this.fb.control(''));
}
deleteCompany(index) {
let control = <FormArray>this.myForm.controls.companies;
control.removeAt(index);
}
}错误:还没有在此数组中注册的窗体控件。如果您正在使用ngModel,您可能需要检查下一个滴答(例如,使用setTimeout)。
发布于 2019-12-24 14:05:20
如果尝试从控件设置companies,则该值必须是数组,并确保添加数组值的新窗体控件基。
product = {
companies:['company 01' , 'company 02']
} ngOnInit() {
// make sure you have set a default value to product like {companies:[]}
for (let p of this.product.companies) {
this.addNewCompany();
}
this.myForm.controls['companies'].setValue(this.product.companies);
}如果使用setValue方法,则必须提供控件长度的值基,否则会在数组控件长度小于或大于数组控件长度时抛出错误,数组值必须与控件长度相同。 patchValue 没有关于控制长度的约束,但这意味着如果将公司设置为10,而您只有一个控件,则只会得到第一家公司,而另一家将因此消失,在这种情况下,请确保使用setValue或patchValue,但确保有长度与值相同的控件。
发布于 2019-12-24 14:34:05
您可以将创建form的逻辑移动到ngOnInit中。就像这样:
@Input()
public product: Product;
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
companies: this.fb.array(this.product ? this.product.companies.map(company => new FormControl(company)) : [])
});
}
addNewCompany() {
this.companies.push(new FormControl());
}
deleteCompany(i) {
this.companies.removeAt(i);
}
get companies() {
return ( < FormArray > this.myForm.get('companies'));
}但是,可能无法保证product @Input属性将按时间设置。
因此,为了确保在使用companies FormArray创建companiesFormArray之前设置了该属性,您可能需要通过服务来初始化其中的product属性。
您必须创建一个为您执行此任务的DataService:
import { Injectable } from '@angular/core';
import { Product } from './product.model';
@Injectable()
export class DataService {
product: Product;
constructor() { }
setProduct(product) {
this.product = product;
}
}然后,您可以将其注入父组件以设置product,并将其注入子组件中以获得ngOnInit生命周期钩子方法中的产品。就像这样:
myForm: FormGroup;
constructor(
private fb: FormBuilder,
private dataService: DataService
) {}
ngOnInit() {
this.myForm = this.fb.group({
companies: this.fb.array(this.dataService.product ? this.dataService.product.companies.map(company => new FormControl(company)) : [])
});
}
addNewCompany() {
this.companies.push(new FormControl());
}
deleteCompany(i) {
this.companies.removeAt(i);
}
get companies() {
return ( < FormArray > this.myForm.get('companies'));
}这是一个供您参考的工作样品演示。
https://stackoverflow.com/questions/59469780
复制相似问题