javascript - 在 Angular 7 中处理大型响应式表单
问题描述
我试图找到一种更好的方法来处理复杂的角度形式。表格真的很大,我需要找到一种方法来降低复杂性。
以下是表单结构的示例:
{
"fieldA" : ...,
"fieldB" : ...,
"fieldC" : ...,
"profile": {
"username": ...,
"email": ...,
"firstName": ...,
"lastName": ...,
...
},
"settings": {
"enableEmailNotification": ...,
"notificationsEmail": ..., // required when enableEmailNotification
...
},
...
}
在某些情况下,验证器会即时更改,例如,当enableEmailNotification=true
组件将Required
验证器添加到notificationsEmail
以下是研究的选项:
选项 #0 - 经典
这种方法使用一种形式和一种组件。
优点:
- 代码很多,但是很简单
缺点:
- 所有逻辑都在一个地方。就我而言,这个组件变得太大并且难以阅读或维护
- UI也变得足够大
选项 #1 - 将 FormGroup 传递给子组件
这种方法将作为属性发送formGroup
到内部组件。@Input()
优点:
- 缩小部分视图
缺点:
- 表单创建和验证规则仍在父组件上
- 仅缩小视图大小
- 验证逻辑在根组件中创建,但在子组件中显示错误
选项 #2 - 创建自定义 ControlValueAccessor
基于这篇文章,我们可以创建自定义的 ControlValueAccessor,它将为表单的一部分返回一个对象。
优点:
- 以多种形式拆分形式。表格可以分成更小的独立部分。
缺点:
- 为表单值保留 JS 对象。看起来不太好
解决方案
我对大型复杂表单的策略是拥有一个包装组件和子组件。每个子组件都有自己的表单服务,并且包装器有一个主表单服务,其中注入了子表单服务,考虑一下
@Component({
selector: 'form-wrapper',
template: `
<form [formGroup]="form" (submit)="save()">
<sub-form-a></sub-form-a>
<sub-form-b></sub-form-b>
<input type="submit" value="Submit Form">
</form>
`,
providers: [MasterFormService, FormAService, FormBService]
})
export class FormWrapper {
constructor(private formService: MasterFormService) { }
save() {
// whatever save actions here
}
}
@Component({ // form b compoent is basically the same
selector: 'sub-form-a',
template: `
... whatever template belongs to form a ..
`
})
export class FormAComponent {
form: FormGroup
constructor(private formService: FormAService) {
this.form = this.formService.form;
// form a specific actions
}
}
@Injectable()
export class MasterFormService {
form: FormGroup;
constructor(private fb: FormBuilder, formAService: FormAService, formBService: FormBService) {
this.form = this.fb.group({
groupA: this.formAService.form,
groupB: this.formBService.form,
});
}
}
@Injectable() // formB service is basically the same
export class FormAService {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
.. whatever fields belong to form a ..
});
}
}
此方法创建高度可重用的子表单,并允许您模块化/隔离表单逻辑和模板。我经常发现子表单通常属于多个地方,因此它使我的代码非常干燥。特别是在您的示例中,您可以轻松地在应用程序的其他地方重用设置表单和配置文件表单组件。一两次我什至再次嵌套这个结构以获得极其复杂的形式。
缺点是结构可能看起来很复杂,但你很快就习惯了。
推荐阅读
- dart - Using setState in separate BottomNotifcationBar class back to the main class
- ios - 如何找出 UITableView 中的哪个特定行收到了强制触摸事件?
- python - Why python not show in path icon?
- powershell - 窗口:命令获取当前磁盘速度输入/输出
- python - How to check if ax is polar projection in matplotlib?
- vb.net - 1 个按钮 3 个功能 Vb.net
- django - 自动填充 slug 字段在 django 中不起作用
- angular - Angular Kendo:布尔值的 kendo-grid-column 过滤器标签
- javascript - Ajax 表单提交地址
- python - Python 不允许我调用方法