gpt4 book ai didi

javascript - 在 Angular 7 中处理大型响应式表单

转载 作者:太空狗 更新时间:2023-10-29 17:50:53 25 4
gpt4 key购买 nike

我正在尝试找到一种更好的方法来处理复杂的 Angular 形式。表单真的很大,我需要找到一种方法来降低复杂性。

这是一个表单结构的例子:

{
"fieldA" : ...,
"fieldB" : ...,
"fieldC" : ...,
"profile": {
"username": ...,
"email": ...,
"firstName": ...,
"lastName": ...,
...
},
"settings": {
"enableEmailNotification": ...,
"notificationsEmail": ..., // required when enableEmailNotification
...
},
...
}

有些情况下验证器会在运行中发生变化,例如当enableEmailNotification=true 时,组件会添加Required 验证器到notificationsEmail

以下是经过研究的选项:

选项 #0 - 经典

sample on github

这种方法使用一种形式和一种组件。

优点:

  • 代码很多,但很简单

缺点:

  • 所有逻辑都在一个地方。就我而言,这个组件变得太大,难以阅读或维护
  • UI 也变得足够大

选项 #1 - 将 FormGroup 传递给子组件

sample on github

此方法将 formGroup 作为 @Input() 属性发送到内部组件。

优点:

  • 缩小部分 View

缺点:

  • 表单创建和验证规则仍在父组件上
  • 只有 View 尺寸减小了
  • 验证逻辑在根组件中创建,但在子组件中显示错误

选项 #2 - 创建自定义 ControlValueAccessor

sample on github

基于 this article我们可以创建自定义 ControlValueAccessor ,它将为表单的一部分返回一个对象。

优点:

  • 以多种形式拆分表格。表单可以拆分为更小的独立部分。

缺点:

  • 为表单值保留 JS 对象。看起来不太好

最佳答案

我对大型复杂表单的策略是使用包装器组件和子组件。每个子组件都有自己的表单服务,包装器有一个主表单服务,其中注入(inject)了子表单服务,考虑一下

@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 ..
});
}
}

此方法创建高度可重用的子表单,并允许您模块化/隔离表单逻辑和模板。我经常发现子表单通常属于不止一个地方,所以它使我的代码非常干燥。特别是在您的示例中,您可以轻松地在应用程序的其他地方重用设置表单和配置文件表单组件。一两次我什至为一个极其复杂的形式再次嵌套了这个结构。

缺点是结构可能看起来很复杂,但您很快就会习惯。

关于javascript - 在 Angular 7 中处理大型响应式表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57516787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com