我是新手。我们正在尝试使用Angular反应性表单
来构建大型表单 此示例的PFA stackblitz链接。我有一个父级组件person-form及其两个子级组件person-job和person-info,每个组件中都包含几个字段。
我有两个无法解决的困难。
1)我希望用户完全填写父表格,然后在最后提交。但是,如果我先填写信息详细信息,然后再填写工作详细信息表格,然后再返回信息;信息中的详细信息不存在。如何使用反应式表单方法将填写的详细信息保留在表单中。这是在子窗体导航上发生的。
2)其次,我想将两种形式的结果合并为一个json并将其发送到父形式组件,即person-form。如何实现这一目标。我现在可以得到
{title: "XYZ", salary: "0000"}
// and
{name: "ABC", age: "12"}
但是我想要这样的东西:
{
combinedForm : {
info:{name: "ABC", age: "12"},
job:{title: "XYZ", salary: "0000"}
}
}
// OR
{
combinedForm : {
name: "ABC", age: "12",title: "XYZ", salary: "0000"
}
}
这样我就可以轻松地一次从服务器发送或接收数据。
答案 0 :(得分:0)
如果您对使用路由实现此目标不满意,则可以选择几种方法。
在开始讨论之前,您可能会发现只使用制表符机制而不进行路由会更容易。
这里最简单的解决方案是在组件之间共享表单的共享服务。
制作如下表格服务:
@Injectable()
export class PersonFormService {
private _form: FormGroup;
get form() {
return this._form;
}
constructor(private fb: FormBuilder) {
this._form = this.fb.group({
title: ['',Validators.required],
salary:['',Validators.required],
name: ['',Validators.required],
age:['']});
}
}
然后在您的父级提供此表单服务:
@Component({
selector: 'app-person-form',
templateUrl: './person-form.component.html',
styleUrls: ['./person-form.component.css'],
providers: [PersonFormService]
})
然后在您的组件中使用表格:
export class PersonJobComponent implements OnInit {
constructor(private personFormService:PersonFormService) { }
formJob:FormGroup;
ngOnInit() {
this.formJob= this.personFormService.form;
}
submit(){
console.log(this.formJob.value);
}
}
和
export class PersonInfoComponent implements OnInit {
constructor(private personFormService: PersonFormService) { }
form:FormGroup;
ngOnInit() {
this.form=this.personFormService.form;
}
}
现在,您将在两个组件中都拥有整个表单。
有效的堆叠闪电战:https://stackblitz.com/edit/angular-qrym5k
如果要出于验证目的或其他目的而分别对待这两个子表单,只需将服务中的表单结构重构为2个表单组。
类似:
@Injectable()
export class PersonFormService {
private _form: FormGroup;
get combinedForm() {
return this._form;
}
get jobForm() {
return this._form.get('job') as FormGroup;
}
get infoForm() {
return this._form.get('info') as FormGroup;
}
constructor(private fb: FormBuilder) {
this._form = this.fb.group({
info: this.fb.group({
name: ['',Validators.required],
age:['']
}),
job: this.fb.group({
title: ['',Validators.required],
salary:['',Validators.required]
})
});
}
}
然后只需在各自的组件中适当使用personFormService.infoForm或.jobForm。
答案 1 :(得分:0)
您可以使用服务在两个或多个组件之间共享表单数据。您可以使用服务名称PersonFormService
。服务将是这样的:
import { Injectable } from '@angular/core';
@Injectable()
export class PersonFormService {
personForm: PersonForm;
constructor() {
this.personForm = new PersonForm();
}
set infoDetails(info) {
this.personForm.info = info;
}
set jobDetails(job) {
this.personForm.job = job;
}
get infoDetails() {
return this.personForm.info;
}
get jobDetails() {
return this.personForm.job;
}
}
export class PersonForm {
info: any;
job: any;
constructor() {
this.job = {};
this.info = {};
}
}
现在在这两个组件中,您都可以使用以下服务:
person-job.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { FormGroup } from '@angular/forms';
import { Validators } from '@angular/forms';
import { PersonFormService } from '../../person-form.service';
@Component({
selector: 'app-person-job',
templateUrl: './person-job.component.html',
styleUrls: ['./person-job.component.css']
})
export class PersonJobComponent implements OnInit {
constructor(private fb: FormBuilder, private formService: PersonFormService) { }
formJob:FormGroup;
completeForm: any;
ngOnInit() {
this.formJob=this.fb.group({
title: ['',Validators.required],
salary:['',Validators.required]});
this.formJob.patchValue(this.formService.jobDetails);
}
submit(){
console.log(this.formJob.value);
this.formService.jobDetails = this.formJob.value;
}
}
person-info.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { FormGroup } from '@angular/forms';
import { Validators } from '@angular/forms';
import { PersonFormService } from '../../person-form.service';
@Component({
selector: 'app-person-info',
templateUrl: './person-info.component.html',
styleUrls: ['./person-info.component.css']
})
export class PersonInfoComponent implements OnInit {
constructor(private fb: FormBuilder, private formService: PersonFormService) { }
form:FormGroup;
ngOnInit() {
this.form=this.fb.group({
name: ['',Validators.required],
age:['']});
this.form.patchValue(this.formService.infoDetails);
}
submitForm() {
console.log("submit")
this.formService.infoDetails = this.form.value;
}
}
现在要解决您的第二个问题,您可以使用spread运算符将两个表单合并为一个表单。您的代码将如下所示:
this.completeForm = {...this.formService.infoDetails, ...this.formService.jobDetails }
查看完整的 stackblitz 演示here