我在ReactiveForm
FormControl
上汇总了一个货币属性指令,该指令在输入事件(onKeyDown)上使用@HostListener
来删除所有无效字符(字母和符号)因为它们被输入到输入中,但允许数字和小数。 但是,如果您在空输入字段中键入无效字符(即a
)并且指令删除它,则模型不会更新。
我已使用currency指令添加了plunker设置。要了解我的问题,请遵循以下步骤:
123a
您在输入中未获得a
,因为不允许使用任何字母,并且因为表单无效而禁用该按钮(好) 123.456
您未在输入中获得6
,因为只允许2位小数,并且由于表格无效而禁用该按钮(好)< /强> a
您未在输入中获得a
,但是对帐已启用,因为模型认为其中包含a
,即使用户界面没有&{ #39; t显示(差错) 您可以通过单击按钮并查看记录this.form.value
的控制台并显示{ amount: 'a' }
来验证模型是否未更新。如果您键入有效字符,则模型将仅包含该字符,并且a
将被删除。因此,只有在这种情况下,模型才能正确更新。
这是AngularJS中使用ngModel validator and parser pipes
,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;
}
答案 0 :(得分:7)
所以我确实使用NgControl
找到了一个解决方案,我注入private ngControl: NgControl
然后访问了它的控件属性this.ngControl.control.patchValue(newValue);
,它更新了ReactiveForm
中的输入字段模型在我的onKeyDown
活动中 - 请参阅plunker
但使用EventEmitter
实际上是一种更好的解决方案,可以将值从输入传递给父表单 - {{3 (感谢Todd Motto和他的Ultimate Angular课程)
答案 1 :(得分:0)
随着最近的角度4发布,引入了一个新指令来处理这些场景
<input [name]="fullName" pattern="[a-zA-Z ]*" [(ngModel)]="...">
在模式中,您可以指定任何正则表达式
<强> Docs 强>
更新:根据评论,如果您尝试限制用户输入字符,则可以使用自定义指令。
使用以下代码作为指令功能
@HostListener('keydown') onKeydown() {
let value= this.el.nativeElement.value;
let key= value.charCodeAt(value.length -1])
let strippedString ='';
if(!((key > 64 && key < 91) || (key> 96 && key< 123) || key== 8 || key== 32 || (key>= 48 && key<= 57)){
strippedString = this.el.nativeElement.value.substring(0,value.length-1)
this.el.nativeElement.value = strippedString
}
<强> LIVE DEMO 强>