我必须使用反应式表单来做多步骤的大型表单,而我却面临性能问题。 表单中的几乎所有字段都应基于某些下拉菜单,单选按钮等的选择而具有显示/隐藏条件。
为便于理解,我在顶部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;
}
}
答案 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">