简体   繁体   English

Angular2自定义指令可防止与正则表达式不匹配的字符

[英]Angular2 Custom directive to prevent characters which doesn't match a regexp

I did create a directive which prevents any character to be typed in an input if it doesn't match a given pattern. 我确实创建了一个指令,以防止任何字符如果不匹配给定模式,则不能在输入中键入任何内容。

import { Directive, Input, Output, HostListener, EventEmitter } from "@angular/core"


@Directive({
 selector: '[ngModel][typingPattern]'
})

export class TypingPatternDirective  {

 @Input() typingPattern: string
 @Input() ngModel
 @Output() ngModelChange = new EventEmitter()
 @Input() global: boolean = true // Global modifier
 private oldValue: any

 /* On key down, we record the old value */
 @HostListener('keydown', ['$event'])
 onKeyDown($event) {
   this.oldValue = $event.target.value
 }

 @HostListener('input', ['$event'])
 onInput($event) {
   if (!$event.target.value.match( new RegExp(this.typingPattern, this.global ? 'g' : '')) ) {
     $event.target.value = this.oldValue.trim()
   }
   this.ngModelChange.emit($event.target.value)
 }

 @HostListener('paste', ['$event'])
 onPaste($event) {
   this.onInput($event)
 }
}

And here is how I use it on a input element: 这是我在输入元素上使用它的方式:

 <input type="text" [ngModel]="..." [typingPattern]="$[0-9]{0,8}^" required>

The only bug I currently have happens if in that particular example I type any characters like h . 如果在该特定示例中键入任何字符(例如h ,则当前发生的唯一错误。 The key is gonna be prevented by my directive, but the required property is gonna considered that a character has been added and thus set the input to valid even though my ngModel value is empty and nothing is displayed. 该键将被我的指令阻止,但是必需的属性将被认为已添加了一个字符,因此即使我的ngModel值为空并且什么也不显示,输入还是设置为valid I probably need to event.preventDefault() but I am not sure where. 我可能需要event.preventDefault()但是我不确定在哪里。

I manage to get around this issue by encapsulating the this.ngModelChange.emit($event.target.value) 我设法通过封装this.ngModelChange.emit($event.target.value)来解决此问题。

in a setTimeout() setTimeout()

by doing so, the input validation is retriggered again after, and thus the state of my input get updated correctly (the directive can thus be used correctly with required or other validators). 这样,输入验证将在此之后再次触发,从而正确更新了我的输入状态(因此,该指令可与required或其他验证程序一起正确使用)。 It works for now, but it's definitely a bit hacky, and a better handler of the events should lead to a better solution. 它现在可以使用,但是绝对有点麻烦,更好的事件处理程序可以带来更好的解决方案。

If i'm understanding what you're trying to do, you want to have your input filtered out by the regex passed to typingPattern. 如果我了解您要执行的操作,则希望通过正则表达式将输入过滤掉,然后将其传递给typePattern。 If so, then your ngModelChange EventEmitter should be emitting the 'new value' after it has been checked (and cleaned) by the RegEx. 如果是这样,则您的ngModelChange EventEmitter应该在RegEx检查(并清除)后发出“新值”。 So, if the user types, in sequence: 1,2,y, then your ngModelChange should emit: 1, 12, 12. 因此,如果用户按顺序输入:1、2,y,则您的ngModelChange应该发出:1、12、12。

If the above is true, then you need to capture the old value of your input BEFORE the keydown event. 如果上述情况成立,那么您需要在keydown事件之前捕获输入的旧值。 Then, on each keydown, if the new character is acceptable, you can ngModelChange.emit the value of your input. 然后,在每次击键时,如果可接受新字符,则可以ngModelChange.emit输入的值。 If, however, the new character is not acceptable, then you should emit the old value that you previously stored. 但是,如果新字符不可接受,则应发出以前存储的旧值。

Does that make sense? 那有意义吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM