我确实创建了一个指令,如果它与给定的模式不匹配,就会阻止在输入中输入任何字符。
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()
,但我不知道在哪里。
答案 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输入的值。但是,如果新字符不可接受,则应发出先前存储的旧值。
这有意义吗?