在我工作的,我們正在開發多種形式的大規模應用,用戶需要填寫,以便爲我們的程序註冊公司。當所有問題都得到解答後,用戶就會到達一個總結所有答案的部分,突出顯示無效答案,並讓用戶有機會重新訪問任何前面的表單步驟並修改答案。該邏輯將在一系列頂級部分中重複出現,每個部分都有多個步驟/頁面和一個摘要頁面。角2 - 大規模的申請表格處理
爲了實現這一點,我們已經創建了每個單獨步驟的形式的組分(它們是類別,如「個人信息」或「資格」等)與它們各自的路線沿着和用於摘要頁面的部件。
爲了保持儘可能乾燥,我們開始創建一個「主」服務,適用於所有不同形式的步驟(值,有效性等)的信息。
import { Injectable } from '@angular/core';
import { Validators } from '@angular/forms';
import { ValidationService } from '../components/validation/index';
@Injectable()
export class FormControlsService {
static getFormControls() {
return [
{
name: 'personalDetailsForm$',
groups: {
name$: [
{
name: 'firstname$',
validations: [
Validators.required,
Validators.minLength(2)
]
},
{
name: 'lastname$',
validations: [
Validators.required,
Validators.minLength(2)
]
}
],
gender$: [
{
name: 'gender$',
validations: [
Validators.required
]
}
],
address$: [
{
name: 'streetaddress$',
validations: [
Validators.required
]
},
{
name: 'city$',
validations: [
Validators.required
]
},
{
name: 'state$',
validations: [
Validators.required
]
},
{
name: 'zip$',
validations: [
Validators.required
]
},
{
name: 'country$',
validations: [
Validators.required
]
}
],
phone$: [
{
name: 'phone$',
validations: [
Validators.required
]
},
{
name: 'countrycode$',
validations: [
Validators.required
]
}
],
}
},
{
name: 'parentForm$',
groups: {
all: [
{
name: 'parentName$',
validations: [
Validators.required
]
},
{
name: 'parentEmail$',
validations: [
ValidationService.emailValidator
]
},
{
name: 'parentOccupation$'
},
{
name: 'parentTelephone$'
}
]
}
},
{
name: 'responsibilitiesForm$',
groups: {
all: [
{
name: 'hasDrivingLicense$',
validations: [
Validators.required,
]
},
{
name: 'drivingMonth$',
validations: [
ValidationService.monthValidator
]
},
{
name: 'drivingYear$',
validations: [
ValidationService.yearValidator
]
},
{
name: 'driveTimesPerWeek$',
validations: [
Validators.required
]
},
]
}
}
];
}
}
即正在使用的所有組件以設置用於每個HTML形式綁定,通過,以及通過摘要頁面訪問相應對象密鑰和創建嵌套形式組的服務,其表示層僅受單向約束(模型 - >視圖)。
export class FormManagerService {
mainForm: FormGroup;
constructor(private fb: FormBuilder) {
}
setupFormControls() {
let allForms = {};
this.forms = FormControlsService.getFormControls();
for (let form of this.forms) {
let resultingForm = {};
Object.keys(form['groups']).forEach(group => {
let formGroup = {};
for (let field of form['groups'][group]) {
formGroup[field.name] = ['', this.getFieldValidators(field)];
}
resultingForm[group] = this.fb.group(formGroup);
});
allForms[form.name] = this.fb.group(resultingForm);
}
this.mainForm = this.fb.group(allForms);
}
getFieldValidators(field): Validators[] {
let result = [];
for (let validation of field.validations) {
result.push(validation);
}
return (result.length > 0) ? [Validators.compose(result)] : [];
}
}
後,我們開始使用的組件以下語法,以達到在主表單服務指定的表單控件:
personalDetailsForm$: AbstractControl;
streetaddress$: AbstractControl;
constructor(private fm: FormManagerService) {
this.personalDetailsForm$ = this.fm.mainForm.controls['personalDetailsForm$'];
this.streetaddress$ = this.personalDetailsForm$['controls']['address$']['controls']['streetaddress$'];
}
這似乎是在我們缺乏經驗的眼睛代碼味道。考慮到我們最終將擁有的部分數量,我們對這樣的應用程序如何擴展會有強烈的擔憂。
我們已經討論了不同的解決方案,但我們不能拿出一個利用角的形式引擎,使我們能夠保持我們的驗證層次結構完好無損,也很簡單。
有沒有更好的方法來實現我們正在嘗試做的事情?
謝謝@ovangle!我認爲你的建議非常接近我想要達到的目標,並提供足夠的思考。 – Manolis