[英]Angular 6 event.stopPropagation() not working in directive (template-driven form takes event.data already)
我正在尝试使公民编号组件在表单中使用。 它为ngModel实现ControlValueAccessor。
export class CitizenNumberComponent implements ControlValueAccessor {
private _value: string;
@Input() placeholder = '';
@Input() required = true;
get value(): string {
return this._value;
}
set value(value: string) {
this._value = value;
this.propagateChange(value);
}
// registers 'fn' that will be fired when changes are made
// this is how we emit the changes back to the form
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
// not used, used for touch input
registerOnTouched(fn: any): void { }
// this is the initial value set to the component
writeValue(value: string): void {
if (value) {
this._value = value;
}
}
// the method set in registerOnChange to emit changes back to the form
propagateChange = (_: any) => { };
}
我制定了一个NumberDirective来限制除0-9数字之外的输入。
在numberDirective中,我使用了'input'事件,因为keypress,keydown和keyup无法在android chrome中运行。
@Directive({
selector: 'input[jhiNumbersOnly]'
})
export class NumberDirective {
private specialKeys: Array<string> = ['Backspace', 'Delete', 'Insert', 'Tab', 'End', 'Home', 'ArrowRight', 'ArrowLeft'];
@HostListener('input', ['$event']) onInput(event) {
const key = event['data'];
// Allow Backspace, tab, end, and home keys
if (this.specialKeys.indexOf(key) !== -1) {
return;
}
const initalValue = event.target['value'];
event.target['value'] = initalValue.replace(/[^0-9]*/g, '');
if (initalValue !== event.target['value']) {
event.stopPropagation();
}
}
}
最后,一切正常,但所有事件已停止,该模型采用了该值。
例如,我输入的最大长度为11。输入10个数字后,如果输入的某些键(0-9除外)将是有效的。
在stackblitz中查看组件;
你能帮我解决我的问题吗?
您应该用keydown
处理程序替换input
处理程序。 然后,如果密钥是好的,则什么也不做,否则,防止事件发生。
问题是,如果您监听输入事件,那将为时已晚, ngModel
将被更新,因此您必须监听keydown
事件并对其进行适当的过滤。
@HostListener('keydown', ['$event']) onKeyDown(e: KeyboardEvent) {
if (this.specialKeys.indexOf(e.key) !== -1 || new RegExp(/[0-9]/g).test(e.key)) {
return;
}
e.preventDefault();
}
我在您的stackblitz演示中测试了此代码,并且可以正常工作。
编辑 :您提到您不能使用keydown处理程序,抱歉。
我设法使其与<input>
元素上的oninput
处理程序一起使用,并删除了输入上的指令:
<div class = "form-group">
<label class = "form-control-label label-color" for = "citizenNumber">Citizen Number
</label>
<input type = "text"
class = "form-control input-css"
name = "citizenNumber"
id = "citizenNumber"
#citizenNumber="ngModel"
oninput="this.value = this.value.replace(/[^0-9]/g, '');"
[(ngModel)] = "value"
[placeholder] = "placeholder"
minlength = "11"
maxlength = "11"
[required] = "required">
<div *ngIf = "citizenNumber.invalid && (citizenNumber.dirty || citizenNumber.touched)"
class = "form-text text-danger">
<small *ngIf = "citizenNumber.errors.required">This field is required.</small>
<small *ngIf = "citizenNumber.errors.minlength">This field must be 11 characters.</small>
<small *ngIf = "citizenNumber.errors.invalidTc">This is not a citizen number</small>
</div>
</div>
这是更新的Stackblitz 。
希望有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.