Angular反应式表单--用*ngIf隐藏一些字段--性能问题。

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

我必须使用反应式表单做一个多步骤的大表单,我面临着一个性能问题,几乎所有表单中的字段都应该根据一些Dropdowns和单选按钮等的选择来显示隐藏条件。

为了便于理解这个问题,我在顶部添加了以下内容。Debug counter: {{counter}}

调用的方法是 getCondition()multi-step-form.component.ts 并用于 multi-step-form.component.html 第43行。

我知道在*ngIf里面使用方法是不好的,但是我不知道如何解决这个问题。我需要在每次改变表单时检查显示条件。

我试着将这种情况复制到 叠加闪电战. 我正在使用像在例子中的一个复杂的数据模型。

我的问题是,在这种情况下,不使用模板中的方法来显示隐藏字段的最佳解决方案是什么?

下面你可以看到我目前的方法。

getDisplayCondition(field, i, value?: boolean) {
switch (field) {
    case 'video': {
        return this.masterForm[i].controls['resultMedia'].value === 'video';
    }
    case 'image': {
        return this.masterForm[i].controls['resultMedia'].value === 'image';
    }
    case 'influence': {
        return this.masterForm[i].controls['influence'].value === 'yes';
    }
    case 'radar': {
        return this.radarList.length;
    }
    case 'innovationRadar': {
        return this.masterForm[i].controls['isRadar'].value === 'yes';
    }
    case 'isMember': {
        return value;
    }
    default: {
        return true;
    }
}
angular reactive-forms
2个回答
1
投票

你有2个选择。

1 - 使用管道而不是函数,管道默认是纯函数,这意味着只有在数据变化时才会被调用,而不是在每次变化检测运行时。

@Pipe({name: 'displayField'})
export class DisplayFieldPipe implements PipeTransform {
  transform(masterForm: form, i: number, value: boolean): boolean {
    switch (field) {
        case 'video': {
            return this.masterForm[i].controls['resultMedia'].value === 'video';
        }
        case 'image': {
            return this.masterForm[i].controls['resultMedia'].value === 'image';
        }
        case 'influence': {
            return this.masterForm[i].controls['influence'].value === 'yes';
        }
        case 'radar': {
            return this.radarList.length;
        }
        case 'innovationRadar': {
            return this.masterForm[i].controls['isRadar'].value === 'yes';
        }
        case 'isMember': {
            return value;
        }
        default: {
            return true;
        }
    }
}

2 - 构建一个对象,包含你的字段是否应该被显示。你需要订阅表单valueChanges,并在每次重要的值发生变化时更新该对象。它基本上会调用你的getDisplayCondition,但它不会返回一个布尔值,而是会修改ngIfs中使用的对象。

这个对象会是这样的。

field = { field1: true, field2: false, ...};

而Html。

<input *ngIf="field.field1" id="field1">

1
投票

你可以观察你的组件的变化。

this.form.valueChanges.subscribe(form => {...});

然后,在订阅里面,做你的logc 并设置布尔值到一个控制显示的变量, 然后,在*ngIf指令上使用它。 像这样:

this.form.valueChanges.subscribe(form => {
  this.displaySomeField = form.field === "some-value";
});

<mat-form-field *ngIf="displaySomeField">
...
</mat-form-field>
© www.soinside.com 2019 - 2024. All rights reserved.