You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular电话掩码指令异常排查:无法清空模型等问题

修复Angular电话掩码指令的三个问题

问题根源与修复方案

针对你遇到的三个问题,我们通过同步模型值与视图值的逻辑调整,直接解决所有异常:


修改后的完整指令代码

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

@Directive({
  selector: '[appPhoneMask]'
})
export class PhoneMaskDirective {

  constructor(public ngControl: NgControl) { }

  @HostListener('ngModelChange', ['$event'])
  onModelChange(event: string) {
    // 过滤所有非数字字符,得到纯数字原始值
    const rawNumber = event.replace(/\D/g, '');
    // 强制截断到10位,解决超长度模型多存的问题
    const truncatedNumber = rawNumber.substring(0, 10);
    // 更新模型为纯数字值,彻底阻止非数字字符存入
    this.ngControl.control?.setValue(truncatedNumber, { emitModelToViewChange: false });
    // 生成格式化视图值并更新输入框
    const formattedValue = this.formatPhoneNumber(truncatedNumber);
    this.ngControl.valueAccessor?.writeValue(formattedValue);
  }

  @HostListener('keydown.backspace', ['$event'])
  keydownBackspace(event: KeyboardEvent) {
    const inputElement = event.target as HTMLInputElement;
    // 将格式化视图值转成纯数字,避免符号干扰退格逻辑
    const currentRawValue = inputElement.value.replace(/\D/g, '');
    // 退格后的值:有内容则删最后一位,无内容则置空
    const newValue = currentRawValue.length > 0 ? currentRawValue.substring(0, currentRawValue.length - 1) : '';
    // 同步更新模型与视图
    this.ngControl.control?.setValue(newValue, { emitModelToViewChange: false });
    this.ngControl.valueAccessor?.writeValue(this.formatPhoneNumber(newValue));
  }

  // 单独提取格式化逻辑,便于后续维护
  private formatPhoneNumber(rawNumber: string): string {
    if (!rawNumber) return '';
    switch (rawNumber.length) {
      case 0:
        return '';
      case 1:
      case 2:
      case 3:
        return `(${rawNumber})`;
      case 4:
      case 5:
      case 6:
        return `(${rawNumber.substring(0, 3)}) ${rawNumber.substring(3)}`;
      default:
        return `(${rawNumber.substring(0, 3)}) ${rawNumber.substring(3, 6)}-${rawNumber.substring(6, 10)}`;
    }
  }
}

各问题的具体修复说明

  1. 退格删除后模型残留值

    • 移除原代码中针对退格的长度限制,统一基于纯数字值处理删除逻辑,避免格式化符号干扰
    • 退格到空时直接将模型设为空字符串,确保视图与模型完全同步
  2. 输入超过10位模型多存一位

    • 在模型更新前强制截断纯数字值到10位,从源头控制模型长度
    • 视图格式化也基于截断后的值生成,保证两者一致性
  3. 非数字字符存入模型

    • 模型仅接收过滤后的纯数字值,彻底阻断非数字字符进入模型
    • 视图负责显示格式化内容,模型存储干净的原始数字,兼顾体验与数据准确性

使用说明

保持你原有的输入框用法即可,指令会自动同步模型与视图的正确值:

<input
  (blur)="validateOther()"
  id="otherPhone"
  [(ngModel)]="selectedCommunicationMethod.value"
  placeholder="Enter phone"
  appPhoneMask
  class="form-control w-50"
  [ngClass]="{'is-invalid': showOtherErrorMsg}"
/>

内容的提问来源于stack exchange,提问作者plasmy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:10:11