Директивное форматирование не поспевает за быстрым вводом - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь отформатировать поле ввода, преобразовав буквы пользователя в действительные инициалы: заглавные буквы, разделенные точкой.

Ввод должен быть отформатирован как пользовательские типы, а не после.

new-customer-form.component.html

<input formatInitials>

format-initials.directive.ts

import { Directive, HostListener } from "@angular/core";

@Directive({
    selector: '[formatInitials]'
})
export class FormatInitialsDirective {
    @HostListener('keyup', [ '$event' ]) private format(event: KeyboardEvent): void {
        const {target} = event;
        const {value} = target;

        const isAlphabeticKeyCode = event.keyCode >= 65 && event.keyCode <= 90;

        if (isAlphabeticKeyCode) { // Only separate with a dot for alphabetic chars 
            target.value = `${value.toUpperCase()}.`;
        }
    }

}

КогдаЯ набираю медленно, форматирование работает нормально, но когда я набираю быстрее, форматирование портится, поэтому вместо P.J.S я получаю PJ.S...

Похоже, что ввод обрабатывается до выполнения директивы.Как я могу убедиться, что ввод обрабатывается только после форматирования?

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

Как упоминалось в предыдущем ответе, keyup нельзя использовать, поскольку вам не нужно оставлять клавишу перед нажатием следующей клавиши во время быстрого набора.

Вместо него необходимо использовать keydown вместе с preventDefault() для манипулирования введенным вводом перед размещением его на входе.

Попробуйте это в вашей директиве

import { Directive, HostListener } from "@angular/core";

@Directive({
  selector: '[formatInitials]'
})
export class FormatInitialsDirective {
  @HostListener('keydown', ['$event']) 
  private format(event: KeyboardEvent): void {
    const { target } = event;
    const { value } = target;

    const isAlphabeticKeyCode = event.keyCode >= 65 && event.keyCode <= 90;

    if (isAlphabeticKeyCode) {
      event.preventDefault();
      target.value += `${event.key.toUpperCase()}.`;
    }
  }
}

Вот рабочий пример для StackBlitz

1 голос
/ 16 июня 2019

С помощью вышеуказанного ответа от @ nash11 я получил его на работу, но у меня возникли проблемы с сохранением значения в моей форме, поэтому я добавил часть об обновлении значения formControl здесь:

import { Directive, HostListener, Input } from '@angular/core';
import { FormControl } from '@angular/forms';

@Directive({
    selector: 'input[formatInitials]',
})
export class FormatInitialsDirective {
    @Input() public formControl: FormControl;

    @HostListener('keydown', ['$event'])
    public format(event: KeyboardEvent): void {
        const { target } = event;
        const isAlphabeticKeyCode = event.keyCode >= 65 && event.keyCode <= 90;

        if (isAlphabeticKeyCode) {
            event.preventDefault();
            (<HTMLInputElement>target).value += `${event.key.toUpperCase()}.`;
            this.formControl.setValue((<HTMLInputElement>target).value);
        }
    }
}
...