我最近一直在做一个具有巨大表单的项目,并且遇到了性能问题。经过一番研究后,我想知道,从反应形式中选择嵌套
FormArrays
到 *ngFor
语句中的更好方法是什么。
例如,我有这样一个表单结构,其中
...
表示FormGroup(在FormArray内)和FormControl(在FormGroups内)的N项:
MainFormGroup {
ParentFormArray {
...
FormGroup {
...
NestedFormArray {
...
FormGroup { ... }
...
}
...
}
...
}
}
在 Angular 15 中,我无法以这种方式渲染 FormArrays,因为它可以在旧的 StackOverflow 问题中找到:
<div *ngFor="let item of form.controls['ParentFormArray'].controls; let i = index"
因为
controls
内部不存在AbstractControl
。所以我们需要直接告诉模板ParentFormArray
是FormArray
的实例。
为此,我们有多种选择(这些只是我找到的):
.ts
中创建一个返回 FormArray
的 getter,但这不允许我们在里面放入参数(例如,FormGroup
的父级
NestedFormArray
FormArray
的方法,并且可以获取一个参数来返回特定 FormGroup 的嵌套 FormArray(也嵌套在父 FormArray 中)据我所知,前两个选项不好,因为每次 ChangeDetection 运行时都会调用 getter 和方法。但是管道呢?如果是反应形式,这个选项是否更可取?
例如我为了测试目的而编写的管道:
@Pipe({ name: "getArray", pure: true })
export class GetArrayPipe {
transform (formGroup: AbstractControl, path?: string): FormArray | null {
return path ? <FormArray>formGroup.get(path) : <FormArray>formGroup;
}
}
像这样使用它:
for parent:
<accordion *ngFor="let parentItem of (ParentFormArray | getArray).controls; let i = index"> // parentItem there would be a FormGroup instance
and for nested:
<accordion *ngFor="let nestedItem of (parentItem | getArray:'NestedFormArray').controls; let i = index"> // get controls of the nested FormArray of the parent FormGroup
或者有没有更好的方法来渲染这样的多级表单?
附注使用
console.log
进行测试,管道的结果很棒:使用方法或 getters log
每次点击都会被调用数十次(使用默认策略的每个 ChangeDetection),而管道在初始渲染时仅被调用 1 次。
迄今为止最好的选择是使用纯管道。使用此选项,Angular 不需要在每个变化检测周期从
FormArray
中提取 FormGroup