繁体   English   中英

Angular 6 event.stopPropagation()在指令中不起作用(模板驱动形式已经接受event.data)

[英]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.

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