[英]Angular2 patchValue in FormArray
As I have previously asked in a question 正如我之前在一个问题中提出的那样
I want to create a nested form where the parent is agnostic to the kid's formControlNames
我想创建一个嵌套表单,其中父对象与kid的
formControlNames
So lets say we have a component componentA.component.ts
所以我们假设我们有一个组件
componentA.component.ts
@Component({
selector: 'common-a',
template: `
<div [formGroup]="parentForm">
<div class="form-group">
<label>Common A[1]</label>
<div >
<input type="text" formControlName="valueA1">
<small>Description 1</small>
</div>
<div class="form-group">
<label>Common A[2]</label>
<div >
<input type="text" formControlName="valueA2">
<small>Description 2</small>
</div>
</div>
`
})
export class ComponentA implements OnInit{
@Input() parentForm: FormGroup;
constructor(private _fb: FormBuilder) {
}
ngOnInit() {
this.parentForm.addControl("valueA1", new FormControl('', Validators.required));
this.parentForm.addControl("valueA2", new FormControl('', Validators.required));
}
}
And the main component. 和主要组成部分。
@Component({
selector: 'main',
template: `
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)">
<div>
<div *ngFor="let c of myForm.controls.componentA.controls; let i=index" class="form-group">
<common-a [parentForm]="c"></common-a>
</div>
<div>
<button type="submit" [disabled]="myForm.invalid">Register!</button>
<a class="button" (click)="add_component()">Add New</a>
<a class="button" (click)="delete_component()">Delete</a>
</div>
</div>
<pre>form value: <br>{{myForm.value | json}}</pre>
</form>
`
})
export class MainComponent implements OnInit{
@Input('group') public myForm: FormGroup;
add_component() {
const control = <FormArray>this.myForm.controls['componentA'];
control.push(this._fb.group({}));
}
delete_component() {
const control = <FormArray>this.myForm.controls['componentA'];
control.removeAt(this.myForm.length-1);
}
constructor(private _fb: FormBuilder) {
}
ngOnInit() {
this.myForm = this._fb.group({
componentA : this._fb.array([this._fb.group({})])
});
}
onSubmit(formValue) {
console.log(formValue);
}
}
My question now is how can I use patchValue
to fetch data from a server endpoint and populate the values of the form array, creating new FormGroups
on demand, always agnostic to the parent. 我现在的问题是如何使用
patchValue
从服务器端点获取数据并填充表单数组的值,按需创建新的FormGroups
,始终与父服务器无关。
The problem with this approach, apart from the stinky architecture, is that I override the patchValue method with my own implementation and push these new groups on demand, since inside the function body I know how many there are, but the kid's OnInit will not be invoked within the function, leaving the values empty. 这种方法的问题,除了臭的架构,我用我自己的实现覆盖patchValue方法并按需推送这些新组,因为在函数体内我知道有多少,但是孩子的OnInit不会在函数内调用,将值保留为空。
var self = this;
this.formArray.patchValue = (value: {[key: string]: any}, {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}) =>{
for(var i = 0; i < Object.keys(value).length; i++ ) {
self.add_new();
}
Object.keys(value).forEach(name => {
if (self.formArray.controls[name]) {
self.formArray.controls[name].patchValue(value[name], {onlySelf: true, emitEvent});
}
});
self.formArray.updateValueAndValidity({onlySelf, emitEvent});
}
And again I think this is bad design. 我再次认为这是糟糕的设计。
static generate() {
return new FormGroup({
valueA1: new FormControl('', Validators.required),
valueA2: new FormControl('', Validators.required)
});
}
Do you have any clean solution for this kind of problem ? 对于这类问题,你有什么清洁的解决方案吗?
Also here's a working plunkr based on my previous question 这也是基于我之前的问题的一个工作的plunkr
Alternative solution for dynamic controls. 动态控制的替代解决方案。
1: Inject ChangeDetectorRef 1:注入ChangeDetectorRef
constructor(private _changeDetectorRef: ChangeDetectorRef) { }
2: Override patchValue 2:覆盖patchValue
this.control = new FormArray([]);
let patchValue = this.control.patchValue;
this.control.patchValue = (value: any, options?: Object) => {
for (let i = this.control.length; i < value.length; i++) {
// Push new item
}
this._changeDetectorRef.detectChanges();
patchValue.apply(this.control, [value, options]);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.