Проблема в Angular с маской и валидатором на входе

#angular #regex #input #angular-validation #input-mask

#angular #регулярное выражение #ввод #angular-проверка #ввод-маска

Вопрос:

У меня проблема с использованием маски и регулярного выражения на входе.

Это ввод:

 <mat-form-field
  >
    <mat-label >HH:mm:ss:SSS</mat-label>
    <input
      matInput
      [formControlName]="duration?.id"
      [id]="duration?.id"
      [name]="duration?.id"
      placeholder="HH:mm:ss:SSS"
      appDurationMask
      type="text"
    />
    <mat-error *ngIf="!isInvalidPattern"
      >{{ duration?.label }} is required</mat-error
    >
    <mat-error *ngIf="isInvalidPattern"
      >invalid pattern must be HH:mm:ss:SSS</mat-error
    >
  </mat-form-field>
  

Функция isInvalidPattern выглядит так:

 get isInvalidPattern() {
    return this.form.controls[this.data.id].errors
      ? this.form.controls[this.data.id].errors.pattern
      : false;
  }
  

Директива mask выглядит так:

     export class DurationMaskDirective {
  constructor(public ngControl: NgControl) {}

  @HostListener('ngModelChange', ['$event'])
  onModelChange(event) {
    this.onInputChange(event, false);
  }

  @HostListener('keydown.backspace', ['$event'])
  keydownBackspace(event) {
    this.onInputChange(event.target.value, true);
  }

  onInputChange(event, backspace) {
    let newVal = event.replace(/D/g, '');
    if (backspace amp;amp; newVal.length <= 6) {
      newVal = newVal.substring(0, newVal.length - 1);
    }
    if (newVal.length === 0) {
      newVal = '';
    } else if (newVal.length <= 2) {
      newVal = newVal.replace(/^(d{0,2})/, '$1');
    } else if (newVal.length <= 4) {
      newVal = newVal.replace(/^(d{0,2})(d{0,2})/, '$1:$2');
    } else if (newVal.length <= 6) {
      newVal = newVal.replace(/^(d{0,2})(d{0,2})(d{0,2})/, '$1:$2:$3');
    } else if (newVal.length <= 9) {
      newVal = newVal.replace(
        /^(d{0,2})(d{0,2})(d{0,2})(d{0,3})/,
        '$1:$2:$3:$4'
      );
    } else {
      newVal = newVal.substring(0, 9);
      newVal = newVal.replace(
        /^(d{0,2})(d{0,2})(d{0,2})(d{0,3})/,
        '$1:$2:$3:$4'
      );
    }
    this.ngControl.valueAccessor.writeValue(newVal);
    this.ngControl.valueAccessor.writeValue(newVal);
  }
  

Проблема довольно проста: когда я записываю что-то во входных данных, что не соответствует шаблону, даже если ничего не видно, для invalidpattern устанавливается значение true .

Если я написал одно число, а затем удалил его, для invalidpattern устанавливается значение true. Если я хорошо написал свой шаблон, то добавьте 1 цифру или букву или что-нибудь еще, даже если единственное, что видно, это хороший шаблон, invalidpattern имеет значение true . Когда я отлаживаю, я вижу, что даже если я удаляю (используя backspace), он все равно сохраняет в памяти последнее число, даже если пользователю ничего не видно.

Например, если на входе я написал 1, а затем использовал backspace, пользователь ничего не видит во входных данных, но значение this.form.controls[this.metadata.id].value равно 1.

Если я напишу 11:11:11:111, затем добавьте 1 в конце, даже если входные данные показывают 11:11:11:111, значение this.form.controls[this.metadata.id].value равно 11:11:11:1111.

Что я могу сделать, чтобы решить эту проблему?

Редактировать

Редактор stackblitz

URL-адрес приложения

Комментарии:

1. Если вы предоставите ссылку на stackblitz или что-то подобное, это поможет.

2. я добавил ссылку для stackblitz в edit