Forms Angular 2-大型申请表';处理

Forms Angular 2-大型申请表';处理,forms,angular,architecture,Forms,Angular,Architecture,在我工作的公司,我们正在开发一个包含多个表单的大型应用程序,用户需要填写这些表单才能注册我们的程序。回答完所有问题后,用户将进入一个部分,该部分总结所有答案,突出显示无效答案,并让用户有机会重新访问前面的任何表单步骤并修改其答案。该逻辑将在一系列顶级部分中重复,每个部分都有多个步骤/页面和一个摘要页面 为了实现这一点,我们为每个单独的表单步骤创建了一个组件(它们是“个人详细信息”或“资格”等类别),以及它们各自的路线和摘要页面的组件 为了让它尽可能干燥,我们开始创建一个“主”服务,它保存所有不同

在我工作的公司,我们正在开发一个包含多个表单的大型应用程序,用户需要填写这些表单才能注册我们的程序。回答完所有问题后,用户将进入一个部分,该部分总结所有答案,突出显示无效答案,并让用户有机会重新访问前面的任何表单步骤并修改其答案。该逻辑将在一系列顶级部分中重复,每个部分都有多个步骤/页面和一个摘要页面

为了实现这一点,我们为每个单独的表单步骤创建了一个组件(它们是“个人详细信息”或“资格”等类别),以及它们各自的路线和摘要页面的组件

为了让它尽可能干燥,我们开始创建一个“主”服务,它保存所有不同表单步骤(值、有效性等)的信息

从'@angular/core'导入{Injectable};
从'@angular/forms'导入{Validators};
从“../components/validation/index”导入{ValidationService};
@可注射()
导出类FormControlsService{
静态getFormControls(){
返回[
{
名称:“personalDetailsForm$”,
小组:{
名称$:[
{
名称:“firstname$”,
验证:[
需要验证器,
验证器。最小长度(2)
]
},
{
名称:“lastname$”,
验证:[
需要验证器,
验证器。最小长度(2)
]
}
],
性别$:[
{
名称:“性别$”,
验证:[
需要验证器
]
}
],
地址$:[
{
名称:“streetaddress$”,
验证:[
需要验证器
]
},
{
名称:“城市$”,
验证:[
需要验证器
]
},
{
名称:“state$”,
验证:[
需要验证器
]
},
{
名称:“zip$”,
验证:[
需要验证器
]
},
{
名称:'country$',
验证:[
需要验证器
]
}
],
电话$:[
{
名称:'phone$',
验证:[
需要验证器
]
},
{
名称:“countrycode$”,
验证:[
需要验证器
]
}
],
}
},
{
名称:'parentForm$',
小组:{
全部:[
{
名称:“parentName$”,
验证:[
需要验证器
]
},
{
名称:“parentEmail$”,
验证:[
ValidationService.emailValidator
]
},
{
名称:'parentOccupation$'
},
{
名称:'parentphone$'
}
]
}
},
{
名称:“职责表单$”,
小组:{
全部:[
{
名称:“hasDrivingLicense$”,
验证:[
需要验证器,
]
},
{
名称:“drivingMonth$”,
验证:[
ValidationService.monthValidator
]
},
{
名称:“drivingYear$”,
验证:[
ValidationService.yearValidator
]
},
{
名称:“每周驱动时间$”,
验证:[
需要验证器
]
},
]
}
}
];
}
}
所有组件都在使用该服务,以便通过访问相应的对象键和创建嵌套的表单组,以及摘要页面(其表示层仅为单向绑定(模型->视图))为每个组件设置HTML表单绑定

导出类FormManagerService{
主要形式:FormGroup;
构造函数(私有fb:FormBuilder){
}
setupFormControls(){
设allForms={};
this.forms=FormControlsService.getFormControls();
for(让我们以这个的形式。形式){
让resultingForm={};
Object.key(form['groups']).forEach(group=>{
设formGroup={};
for(形式为['groups'][group]的let字段){
formGroup[field.name]=['',this.getFieldValidators(field)];
}
resultingForm[group]=这个.fb.group(formGroup);
});
allForms[form.name]=此.fb.group(结果表单);
}
this.mainForm=this.fb.group(所有表单);
}
getFieldValidators(字段):验证程序[]{
让结果=[];
for(让验证field.validations){
结果:推送(验证);
}
返回(result.length>0)-[Validators.compose(result)]:[];
}
}
之后,我们开始在组件中使用以下语法,以访问主窗体服务中指定的窗体控件:

personalDetailsForm$:AbstractControl;
streetaddress$:AbstractControl;
构造函数(专用fm:FormManagerService){
this.personaldailsform$=this.fm.mainForm.controls['personaldailsform$'];
this.streetaddress$=this.personalDetailsForm$['controls']['address$']['controls'][
stepsForm: Array<FormGroup> = [];
getFormGroup(id:number, config: Object): FormGroup {
    let formGroup: FormGroup;
    if(this.stepsForm[id]){
        formGroup = this.stepsForm[id];
    } else {
        formGroup = this.createForm(config); // call function to create FormGroup
        this.stepsForm[id] = formGroup;
    }
    return formGroup;
}
export enum Gender {
  MALE = 'Male',
  FEMALE = 'Female',
  Other = 'Other',
}

export interface Name {
  firstname: string;
  lastname: string;
}

export interface Address {
  streetaddress: string;
  city: string;
  state: string;
  zip: string;
  country: string;
}

export interface Phone {
  phone: string;
  countrycode: string;
}

export interface PersonalDetails {
  name: Name;
  gender: Gender;
  address: Address;
  phone: Phone;
}

export interface MainForm {
  // this is one example out of what you posted
  personalDetails: PersonalDetails;

  // you'll probably want to add `parent` and `responsibilities` here too
  // which I'm not going to do because `personalDetails` covers it all :)
}
@Component({
  selector: 'app-personal-details-form',
  templateUrl: './personal-details-form.component.html',
  styleUrls: ['./personal-details-form.component.css'],
  providers: subformComponentProviders(PersonalDetailsFormComponent)
})
export class PersonalDetailsFormComponent extends NgxSubFormComponent<PersonalDetails> {
  protected getFormControls(): Controls<PersonalDetails> {
    return {
      name: new FormControl(null, { validators: [Validators.required] }),
      gender: new FormControl(null, { validators: [Validators.required] }),
      address: new FormControl(null, { validators: [Validators.required] }),
      phone: new FormControl(null, { validators: [Validators.required] }),
    };
  }
}
@Component({
  selector: 'app-phone-form',
  templateUrl: './phone-form.component.html',
  styleUrls: ['./phone-form.component.css'],
  providers: subformComponentProviders(PhoneFormComponent)
})
export class PhoneFormComponent extends NgxSubFormComponent<Phone> {
  protected getFormControls(): Controls<Phone> {
    return {
      phone: new FormControl(null, { validators: [Validators.required] }),
      countrycode: new FormControl(null, { validators: [Validators.required] }),
    };
  }
}
<div [formGroup]="formGroup">
  <input type="text" placeholder="Phone" [formControlName]="formControlNames.phone">
  <input type="text" placeholder="Country code" [formControlName]="formControlNames.countrycode">
</div>
<div [formGroup]="formGroup">
    <app-name-form [formControlName]="formControlNames.name"></app-name-form>

    <select [formControlName]="formControlNames.gender">
    <option *ngFor="let gender of Gender | keyvalue" [value]="gender.value">{{ gender.value }}</option>
  </select>

  <app-address-form [formControlName]="formControlNames.address"></app-address-form>

  <app-phone-form [formControlName]="formControlNames.phone"></app-phone-form>
</div>
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent extends NgxSubFormComponent<MainForm> {
  protected getFormControls(): Controls<MainForm> {
    return {
      personalDetails: new FormControl(null, { validators: [Validators.required] }),
    };
  }
}
<form [formGroup]="formGroup">
  <app-personal-details-form [formControlName]="formControlNames.personalDetails"></app-personal-details-form>
</form>

<!-- let see how the form values looks like! -->
<h1>Values:</h1>
<pre>{{ formGroupValues | json }}</pre>

<!-- let see if there's any error (works with nested ones!) -->
<h1>Errors:</h1>
<pre>{{ formGroupErrors | json }}</pre>