gpt4 book ai didi

Angular 使用带有@HostListener 的指令来更新 ReactiveForm 的输入值是将输入设置为 ngValid 而不是 ngInvalid

转载 作者:太空狗 更新时间:2023-10-29 18:07:02 26 4
gpt4 key购买 nike

我在 ReactiveForm FormControl 上放置了一个货币属性指令,它在输入事件 (onKeyDown) 上使用 @HostListener 来移除输入时输入的所有无效字符(字母和符号),但允许数字和小数。 但是,如果您在空输入字段中键入无效字符(即a)并且它被指令删除,则模型不是 已更新。

我使用 currency 指令添加了一个 plunker 设置。理解我的问题的步骤:

  1. 键入 123a 您不会在输入中得到 a,因为不允许输入任何字母,并且由于表单无效 (好)
  2. 键入 123.456 您不会在输入中得到 6,因为只允许保留 2 位小数,并且由于表单无效,该按钮被禁用 (好)
  3. 键入 a 您在输入中没有得到 a,但是由于模型认为它有一个 a,因此启用了 butt在其中,即使 UI 不显示它(坏)

您可以通过单击按钮并查看控制台来验证模型是否更新,控制台记录 this.form.value,并显示 { amount: 'a' }。如果您接下来键入一个有效字符,模型将只包含该字符,并且 a 将被删除。所以只有在这种情况下模型没有正确更新。

在 AngularJS 中,使用 ngModel 验证器和解析器管道modelValue$setViewValue$ 很容易解决这个问题render() 来更新并强制 AngularJS 运行一个 $digest。你如何在 Angular 中做到这一点?

这是我的属性指令中的一个片段,它成功地删除了不需要的字符:

@HostListener('input', ['$event'])
onKeyDown(event: KeyboardEvent) {
const input = event.target as HTMLInputElement;

// Only numbers and decimals
let trimmed = input.value.replace(/[^\d\.,]+/g, '');

// Only a single decimal and choose the first one found
if (trimmed.split('.').length > 2) {
trimmed = trimmed.replace(/\.([^\.]*)$/, '$1');
}

// Cannot start with decimal typed or pasted
if (trimmed.indexOf('.') === 0) { trimmed = ''; }

// AngularJS "like" solution would be something like:
// ngModelCtrl.$setViewValue(trimmed);
// ngModelCtrl.$render();
// Angular solution is???

input.value = trimmed;
}

最佳答案

所以我确实找到了一个解决方案,使用 NgControl 注入(inject) private ngControl: NgControl 然后访问它的控制属性 this.ngControl.control.patchValue (newValue);,它在我的 onKeyDown 事件中更新 ReactiveForm 中的输入字段模型 - 请参阅 plunker

但是 基于智能组件和非智能组件的使用,EventEmitter 的使用实际上是一个更好的解决方案,它将值从输入传递到父表单 - plunker (感谢 Todd Motto 和他的 Ultimate Angular 类(class))

关于Angular 使用带有@HostListener 的指令来更新 ReactiveForm 的输入值是将输入设置为 ngValid 而不是 ngInvalid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43380390/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com