0

我有一个这样的html:

<ng-template [ngSwitchCase]="'textbox'">
    <input *ngIf="setting.type==='number'"
           [step]="setting.step"
           [formControlName]="formName"
           [id]="formName"
           [type]="setting.type"
           [placeholder]="setting.placeholder"
           [title]="setting.description"
           (ngModelChange)="onChange($event)">
</ng-template>

在控制器上我有 onChange 函数:

onChange(newValue: string) {
    if (newValue === undefined)
        return;

    this.form.get(this.formName).setValue(<any>parseFloat(newValue));
}

当我调试 onChange 函数的这个调用时,我注意到它仍在调用并且真的不知道为什么。我有一个无限循环。

我的角度包:

"@angular/animations": "8.2.7",
"@angular/cli": "8.3.5",
"@angular/common": "8.2.7",
"@angular/compiler": "8.2.7",
"@angular/core": "8.2.7",
"@angular/forms": "8.2.7",
"@angular/platform-browser": "8.2.7",
"@angular/platform-browser-dynamic": "8.2.7",
"@angular/router": "8.2.7",
"@babel/polyfill": "7.6.0",

您知道我的代码可能有什么问题吗?

4

2 回答 2

2

这可能是因为在 onChange 函数中设置了输入值,它再次更改了输入值并再次调用 onChange。这无限地继续下去。

在需要时将其转换为数字,而不是将字符串解析为数字,然后将其设置回控件,这是不必要的。

parseFloat(this.form.get(this.formName).value)

或者

+this.form.get(this.formName).value

在这种情况下,您不需要每次更改值时都将其解析为数字,而是在需要时解析它。

您可以使用上述行之一将输入解析为每次更改时的数字,但不要再次将其设置为相同的控件。

onChange(newValue: string) {
    parseFloat(this.form.get(this.formName).value)
}
于 2019-12-12T14:01:25.123 回答
1

ControlValueAccessor 方法

请参阅此对类似问题的答案。我知道这个问题并不完全相同,但据我所知,它似乎是一种可靠的方法。ngModelChange该答案建议包装输入组件并实现自定义,而不是使用事件ControlValueAccessor- 请参阅文档

这是这种方法的StackBlitz 示例。但是,它的行为似乎就像blur事件一样,因此ControlValueAccessor与下面的方法相比,在这种情况下可能会过度杀伤力。

模糊事件方法

另一种选择是blur在您的输入中使用事件。与其每次更改值时都尝试更新值,不如float在用户离开控件时更新值(解析为 a )。就像是:

HTML

<ng-template [ngSwitchCase]="'textbox'">
    <input *ngIf="setting.type==='number'"
           [step]="setting.step"
           [formControlName]="formName"
           [id]="formName"
           [type]="setting.type"
           [placeholder]="setting.placeholder"
           [title]="setting.description"
           (blur)="onBlur()">   <!-- this line -->
</ng-template>

组件打字稿

onBlur() {
    const value = this.form.get(this.formName).value;
    this.form.get(this.formName).setValue(<any>parseFloat(value));
}

我在 StackBlitz 上为该blur方法创建的示例。

于 2019-12-12T14:23:19.770 回答