Angular2 Custom指令,用于防止与正则表达式不匹配的字符

时间:2017-03-15 17:13:32

标签: html5 angular typescript

我确实创建了一个指令,如果它与给定的模式不匹配,就会阻止在输入中输入任何字符。

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)
 }
}

以下是我在输入元素上的使用方法:

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

如果在该特定示例中我键入了h之类的任何字符,那么我目前唯一的错误就会发生。我的指令会阻止密钥,但是必需的属性会被认为已经添加了一个字符,因此将输入设置为valid,即使我的ngModel值为空并且没有显示任何内容。我可能需要event.preventDefault(),但我不知道在哪里。

2 个答案:

答案 0 :(得分:1)

我设法通过封装this.ngModelChange.emit($event.target.value)

来解决这个问题

setTimeout()

通过这样做,输入验证在之后再次被重新触发,因此我的输入状态得到正确更新(因此可以使用required或其他验证器正确使用该指令)。它现在有效,但它肯定有点hacky,更好的事件处理程序应该会带来更好的解决方案。

答案 1 :(得分:0)

如果我了解您正在尝试做什么,您希望通过传递给typingPattern的正则表达式过滤掉您的输入。如果是这样,那么你的ngModelChange EventEmitter应该发出&#39; new value&#39;在RegEx检查(和清理)之后。因此,如果用户按顺序键入:1,2,y,那么你的ngModelChange应该发出:1,12,12。

如果上述情况属实,那么您需要在keydown事件之前捕获输入的旧值。然后,在每个keydown上,如果新字符是可接受的,您可以ngModelChange.emit输入的值。但是,如果新字符不可接受,则应发出先前存储的旧值。

这有意义吗?