【问题标题】:Angular - Input [value] bound to form control is not refreshing once with the form control valueAngular - 绑定到表单控件的输入 [值] 不会使用表单控件值刷新一次
【发布时间】:2020-03-05 16:16:45
【问题描述】:

在反应式表单方法中,我有一个绑定了表单控件的滑块。当滑块移动时,表单控件值会更新。 我在滑块附近还有一个输入字段,它显示滑块的值,也可以通过键入来更新它。

<input type="number" class="form-control" id="{{feature.name}}-input"
                [min]="0" [max]="100" [step]="1"
                (change)="onInputChange($event, feature)" [value]="featuresForm.get(feature.name)?.value.value">

我有以下onInputChange 方法,当用户更改输入时更新表单控件的值:

onInputChange(event: any, feature: any) {
const input = this.featuresForm.get(feature.name);

if (event.target.value > 100) {
  input?.setValue({ value: 100 });
  return;
}
if (event.target.value < 0) {
  input?.setValue({ value: 0 });
  return;
}

input?.setValue({ value: event.target.value });
  }

如果我输入 0 到 100 之间的值,一切正常,但如果我输入超出该范围的值,则会发生一些奇怪的事情。

例如:

  1. 输入 105 - 输入值重置为 100
  2. 输入 110 - 输入值保持在 110(或您键入超过 100 的任何其他值),它不再重置
  3. 输入 50 - 输入值重置为 50,一切正常

我认为通过连续执行input?.setValue({ value: 100 });,输入105,然后输入110,表单不会检测到任何变化,因此不会更新[value]="featuresForm.get(feature.name)?.value.value"。有没有办法来解决这个问题?

编辑: Stackblitz 网址:https://stackblitz.com/edit/angular-yb2vgj

请假设第一个输入是一个滑块,其输入类型为

new FormControl({value: 24}), and not new FormControl(24)

使用那里存在的代码和上面发布的场景,我想了解为什么第二个输入在超过 100 的 2 个连续输入后没有正确更新。

【问题讨论】:

  • 使用 ngModel 进行双向绑定
  • @SanjayLohar 或者更好的是,使用响应式表单的方式——使用formControlName
  • @KurtHamilton 是的,这是一个更好的选择。
  • 嗯,我这样编码是有原因的。滑块(有一个formControlName)有一个value: {value: 1} 类型的值,而输入有一个value: 1 类型的值。让输入与我想出的滑块具有相同的值。
  • 您能为此创建一个 stackblitz 实例吗?

标签: javascript angular angular-reactive-forms


【解决方案1】:

我们可以通过许多 hack 来解决它,请找到以下代码。您可以创建另一个属性来跟踪输入表单。我们也可以使用这个属性来更新滑块表单控件的值。

我希望它会有所帮助,否则我会推荐你​​创建一个 stackblitz 实例。

myInputValue = 0;
onInputChange(event: any, feature: any) {
  const input = this.featuresForm.get(feature.name);

  this.myInputValue = (event.target.value > 100) ? 100 :
    (event.target.value < 0)? 0:
    event.target.value;

  input ? .setValue({
    value: this.myInputValue;
  });
}
&lt;input type="number" class="form-control" id="{{feature.name}}-input" [min]="0" [max]="100" [step]="1" (change)="onInputChange($event, feature)" [value]="myInputValue"&gt;

您还可以使用 setTimeout 强制启动更改检测。

onInputChange(event: any) {
    debugger;
    if (event.target.value > 100) {
      setTimeout(() => {
        this.featuresForm.get('slider').setValue(100)
        return;
      })
    }
    if (event.target.value < 0) {
      setTimeout(() => {
        this.featuresForm.get('slider').setValue(0)
      return;
      })
    }

    this.featuresForm.get('slider').setValue( event.target.value )
  }

【讨论】:

  • 你好。感谢您的解决方案。有一个绑定变量可能确实有效,但我想了解我的场景中发生了什么。我还发布了一个 stackblitz 实例。
  • 您正在使用属性绑定来获取第二个输入 [value]="featuresForm.get(feature.name)?.value.value" 的 value 属性。只要模型发生任何变化,Angular就会更新绑定。但是在您的情况下,模型没有变化,因为您在第二次也将其设置为相同的值 100。所以,它没有更新。我提供的代码将是一个理想的解决方案,否则您也可以使用 setTimeout。我也在用 setTimout 解决方案更新我的解决方案。如果你愿意,我已经创建了一个群聊。
  • 是的,我还怀疑通过使用相同的值更新表单输入,不会检测到更改。我将再次尝试使用 angular.io/api/core/ChangeDetectorRef 方法,看看是否可以强制运行更改检测。
  • 很遗憾,ChangeDetectorRef 不起作用。我会接受答案,因为有一个类变量会起作用,但我会继续寻找是否有办法让我的方式工作 - 也许强制更改表单检测或其他东西。
  • 只是想知道你用其他方法有没有成功,可以分享一下吗。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 2019-06-10
  • 2018-06-02
相关资源
最近更新 更多