Angular5/4+:使用 API 调用填充嵌套的 ReactiveForm



我正在尝试填充嵌套ReactiveForm,该嵌套被拆分为几个子表单组件。API 请求完成后,我可以填充父表单,但无法将子FormArray完全循环到子数据计数。以下是我的代码片段:

编辑视图:edit.component.ts

@Component({
selector: 'app-edit',
templateUrl: './edit.component.html',
styleUrls: ['./edit.component.scss']
})
export class EditComponent implements OnInit {
public data: Service = new Service({
id: '',
title: '',
description: '',
service_extras: []
});    
public routeParams: any = {};    
constructor ( 
private route: ActivatedRoute,
private service: ServicesService
) { }
ngOnInit() {
this.setRouteParams();
}
setRouteParams() {
this.route.params.subscribe(params => {
this.routeParams = params;
// getting services using api call
this.getService(this.routeParams);
});
}
getService(params) {
this.service
.getService(params.id)
.subscribe((service: Service) => {
this.data = service;
});
}
}

我正在请求基本组件中的数据edit.component.ts并将收到的数据传递给父表单组件,该组件是EditComponent的子组件

编辑组件.html

<service-form [serviceFormData]="data"></service-form>

service-form.component.ts

@Component({
selector: 'service-form',
templateUrl: './service-form.component.html',
styleUrls: ['./service-form.component.scss']
})
export class ServiceFormComponent implements OnInit {
private _serviceFormData = new BehaviorSubject<Service>(null);    
@Input()
set serviceFormData(value) {
this._serviceFormData.next(value);
}        
get serviceFormData() {
return this._serviceFormData.getValue();
}    
public service: Service;
public serviceForm: FormGroup;
constructor(
private fb: FormBuilder
) { }
ngOnInit() {    
this.serviceForm = this.toFormGroup();
this._serviceFormData.subscribe(data => {
this.serviceForm.patchValue(data);
});
}
private toFormGroup(): FormGroup {           
const formGroup = this.fb.group({
id: [ '' ],
title: [ '' ],
description: [ '' ]
});    
return formGroup;
}
}

我在这里通过订阅其更改然后将值修补到表单@Inputvar 的帮助下接收数据,现在一切都很好,因为一旦收到数据,所有字段都会被填充。问题如下:

service-extra.component.ts

@Component({
selector: 'service-extra-form',
templateUrl: './service-extra.component.html',
styleUrls: ['./service-extra.component.scss']
})
export class ServiceExtraComponent implements OnInit {    
private _extraFormData = new BehaviorSubject<ServiceExtra[]>([]);
@Input() serviceForm: FormGroup;    
@Input() 
set extraFormData(value: ServiceExtra[]) {
this._extraFormData.next(value);
}    
get extraFormData() {
return this._extraFormData.getValue();
}
public extrasForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit()
{
this.serviceForm.addControl('service_extras', new FormArray([]));    
this._extraFormData.subscribe(data => {
this.addNew();
this.extras.patchValue(data);
});
}
private toFormGroup()
{
const formGroup = this.fb.group({
id: [''],
service_id: [''],
title: ['']
});    
return formGroup;
}
public addNew()
{
this.extrasForm = this.toFormGroup();        (<FormArray>this.serviceForm.controls.service_extras).push(this.extrasForm);
}
public removeThis(i: number)
{
(<FormArray>this.serviceForm.controls.service_extras).removeAt(i);
}

get extras(): FormArray {
return this.serviceForm.get('service_extras') as FormArray;
}
}

上面的ngOnInit代码除了添加单个额外表单(即使有两条记录)并填充该表单外什么也没做,即使我删除订阅部分并仅使用this.addNew()也是如此。我怎么知道有多少条记录可供ServiceExtras,以便我可以向FormArray添加那么多FormGroups

编辑 1

堆栈闪电战演示

编辑 2

问题是,如果有两个来自 API 的记录用于服务额外,那么我无法生成两个FormGroups并用数据填充它们,因为在渲染时我无法检测到有多少记录来自 API 的服务额外。

service-form.component.html中,您将serviceForm.value.service_extras属性绑定到extraFormData。但是在初始化service-extra-form组件之前serviceForm没有service_extrasformArray。并在初始化之后。service-extra-form组件中,您调用addRow()方法,该方法准确地用一行填充表单:

service-extra.component.ts

ngOnInit()
{
this.serviceForm.addControl('service_extras', new FormArray([]));    
this._extraFormData.subscribe(data => {
console.log('service_extra_data', data);
this.addNew();
this.extras.patchValue(data);
});
}

service-form.component.html:

<service-extra-form [serviceForm]="serviceForm" 
[extraFormData]="serviceForm.value.service_extras">
</service-extra-form> 

将 [serviceForm] 传递给service-extra-form就足够了。如果你已经通过了form,为什么你通过了serviceForm.value.service_extras

修复,删除多余的问题。用更少的代码😃做同样的事情

服务额外组件

export class ServiceExtraComponent implements OnInit {
@Input() serviceForm: FormGroup;
@Input() extraFormData: ServiceExtra[];
public extrasForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnChanges(data) {
//console.log('ngOnChanges', data);
// if changes only extraFormData
if (data.extraFormData) {
this.extras.setValue([]); // reset
let newExtraArr = data.extraFormData.currentValue;
for (let i = 0; i < newExtraArr.length; i++) {
this.addNew();
this.extras.patchValue(newExtraArr);
}
}
} 
ngOnInit() {
this.serviceForm.addControl('service_extras', new FormArray([]));
}

@Input() extraFormData: ServiceExtra[];在这里从api传递extra_datangOnChangeslyfecycle 钩子上,重置 serviceForm 的service_extrasformArray

堆栈闪电战演示

这是一个修复程序( 堆栈闪电战 这里 )

问题行为的解释:

您的输入以这种方式声明:

<service-extra-form [serviceForm]="serviceForm" [extraFormData]="serviceForm.value.service_extra"></service-extra-form>

因此,输入是表单的值,而不是来自 API 的值。

但是,当您在异步调用 API 后填充表单时,"发送"给ServiceExtraComponent的第一个值是undefined的,并且在您调用的ServiceExtraComponentngOnInit

this.addNew();
this.extras.patchValue(data); 

data = undefined

它在 formArray 中创建一个新的 formGroup,然后使用 undefined 进行修补。

因此,当 API 响应时,您的表单已经使用包含一个项目的 formArray 创建,因此patchValue截断您的service_extra数组以匹配您的表单。

更正可能是将 API 的返回直接绑定为ServiceExtraComponentInput又名:

<service-extra-form [serviceForm]="serviceForm" [extraFormData]="serviceFormData.service_extras"></service-extra-form>

相关内容

  • 没有找到相关文章

最新更新