复制时带有验证器的 Angular Phone 指令不起作用

问题描述 投票:0回答:1

我们在项目中使用 Angular 17 和 Reactive 表单。
我们编写了一个自定义指令,将输出格式化为美国电话号码格式

111-222-3333

我们看到的是,当有人尝试将数字复制到字段中时 - 该字段会被格式化,但验证器仍然说它无效。

HTML 代码

 <input matInput phoneFormatterDirective placeholder="Enter Phone" formControlName="phone"
                class="inputEntry">

打字稿代码

phone: new FormControl(null, [Validators.pattern('^[0-9]{3}-[0-9]{3}-[0-9]{4}$')]),

自定义指令代码

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

@Directive({
  selector: '[phoneFormatterDirective]'
})
export class PhoneFormatterDirective {

  @HostListener('input', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    event.preventDefault();
    const input = event.target as HTMLInputElement;
    console.log(input.value);
    let trimmed = input.value
      .replaceAll('-','')
      .replaceAll('(','')
    .replaceAll(')','')
    .replaceAll(/\s+/g, '');
    if (trimmed.length > 12) {
      trimmed = trimmed.substr(0, 12);
    }
    let numbers = [];
    numbers.push(trimmed.substr(0,3));
    if(trimmed.substr(3,2)!=="")
      numbers.push(trimmed.substr(3,3));
    if(trimmed.substr(6,3)!="")
      numbers.push(trimmed.substr(6,4));

    input.value = numbers.join('-');
    console.log(numbers.join("-"));
  }
}

假设我正在尝试粘贴

(555) 123-1234
- 内容被格式化为
555-123-1234
,但输入仍然无效。
如果我删除一个字符然后手动写入它,这将是有效的 - 这是一种奇怪的行为。
enter image description here

angular angular-reactive-forms
1个回答
0
投票

当前,您将格式化值设置为

HtmlInputElement
的值,但它不会反映在表单控件的状态中。

我建议从

NgControl
获取并设置值,以更新表单控件的状态。

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

@Directive({
  selector: '[phoneFormatterDirective]',
  standalone: true,
})
export class PhoneFormatterDirective {
  constructor(public control: NgControl) {}

  @HostListener('input', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    event.preventDefault();

    const input = this.control.control!;

    console.log(input.value);
    let trimmed = input.value
      .replaceAll('-', '')
      .replaceAll('(', '')
      .replaceAll(')', '')
      .replaceAll(/\s+/g, '');
    if (trimmed.length > 12) {
      trimmed = trimmed.substr(0, 12);
    }

    let numbers = [];
    numbers.push(trimmed.substr(0, 3));

    if (trimmed.substr(3, 2) !== '') numbers.push(trimmed.substr(3, 3));
    if (trimmed.substr(6, 3) != '') numbers.push(trimmed.substr(6, 4));

    input!.setValue(numbers.join('-'), { emitEvent: false });
  }
}

演示@StackBlitz

© www.soinside.com 2019 - 2024. All rights reserved.