通过 *ngFor

问题描述 投票:0回答:1

我最近一直在做一个具有巨大表单的项目,并且遇到了性能问题。经过一番研究后,我想知道,从反应形式中选择嵌套

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
的实例。

为此,我们有多种选择(这些只是我找到的):

  1. .ts
    中创建一个返回
    FormArray
    的 getter,但这不允许我们在里面放入参数(例如,
    FormGroup
     的父级 
    NestedFormArray
  2. 创建一个返回
    FormArray
    的方法,并且可以获取一个参数来返回特定 FormGroup 的嵌套 FormArray(也嵌套在父 FormArray 中)
  3. 创建一个管道来获取这些项目作为 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 angular-reactive-forms angular-pipe angular-changedetection
1个回答
0
投票

迄今为止最好的选择是使用纯管道。使用此选项,Angular 不需要在每个变化检测周期从

FormArray
中提取
FormGroup

© www.soinside.com 2019 - 2024. All rights reserved.