角反应形式-用* ngIf隐藏/显示某些字段-性能问题

时间:2020-06-11 12:53:36

标签: angular reactive-forms

我必须使用反应式表单来做多步骤的大型表单,而我却面临性能问题。 表单中的几乎所有字段都应基于某些下拉菜单,单选按钮等的选择而具有显示/隐藏条件。

为便于理解,我在顶部Debug counter: {{counter}}

上添加了此问题

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

我知道在* ngIf内使用方法不是很好,但我不知道如何解决此问题。我需要在每次更改表单时检查显示条件。

我试图在Stackblitz中复制这种情况。在示例中,我使用的是复杂的数据模型。

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

下面您可以看到我当前的方法。

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;
    }
}

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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">
相关问题