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

使用Angular UI Mask实现SSN失焦部分掩码显示的问题求助

解决angular-ui-mask处理SSN失焦隐藏前5位的问题

嘿,我明白你现在卡在哪了——用angular-ui-mask切换掩码后,SSN的显示完全不是预期的样子对吧?这其实是因为angular-ui-mask的工作逻辑是把输入的字符按顺序填充到掩码里的可编辑位,当你从999-99-9999换成XXX-XX-9999时,它会把原SSN的字符挨个往新掩码的可编辑位置(也就是后面的9999)塞,自然就乱了顺序。

下面给你两种亲测有效的解决方案,你可以根据自己的代码场景选:


方案一:动态处理模型值+切换掩码

这个方法的核心是失焦时把原SSN的前5位替换成XXX-XX-,同时用临时变量存好原始值,聚焦时再恢复回来,这样既保证显示正确,又不会丢数据。

修改后的代码:

HTML部分:

<input 
  class="btnDropdown" 
  id="ssnTextInput" 
  ui-mask="{{uimaskpattern}}" 
  ui-mask-placeholder-char="" 
  ng-focus="applymask(contact)" 
  ng-blur="removemask(contact)" 
  md-minlength="10" 
  md-maxlength="10" 
  name="SSN_{{$index}}" 
  ng-model="contact.contactDetails.attributeDetails.contact" 
  placeholder="Enter SSN"
>

TypeScript部分:

// 用临时变量存原始SSN,避免修改原模型导致真实数据丢失
private originalSSN: string;

public applymask(contact) {
  // 聚焦时把原始SSN和编辑掩码恢复回来
  if (this.originalSSN) {
    contact.contactDetails.attributeDetails.contact = this.originalSSN;
  }
  this.uimaskpattern = "999-99-9999";
}

public removemask(contact) {
  const ssnValue = contact.contactDetails.attributeDetails.contact;
  // 先判断SSN格式是否正确(带分隔符的话长度是11)
  if (ssnValue && ssnValue.length === 11) {
    this.originalSSN = ssnValue;
    // 替换前5位为XXX-XX-,只保留最后4位
    const maskedSSN = `XXX-XX-${ssnValue.substring(6)}`;
    contact.contactDetails.attributeDetails.contact = maskedSSN;
    // 设置对应的掩码让显示格式匹配
    this.uimaskpattern = "XXX-XX-9999";
  }
}

方案二:用自定义过滤器处理显示层

如果你不想修改模型里的真实数据,只想在显示层面做掩码,那自定义一个管道(过滤器)是更好的选择,聚焦时显示原始值,失焦时应用过滤器。

步骤1:先写自定义过滤器

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'ssnMask' })
export class SsnMaskPipe implements PipeTransform {
  transform(value: string): string {
    // 先判断值的有效性,避免报错
    if (!value || value.length !== 11) return value;
    // 只保留最后4位,前面替换成XXX-XX-
    return `XXX-XX-${value.substring(6)}`;
  }
}

步骤2:修改组件模板和逻辑

HTML部分:

<input 
  class="btnDropdown" 
  id="ssnTextInput" 
  ui-mask="{{uimaskpattern}}" 
  ui-mask-placeholder-char="" 
  ng-focus="isFocused = true; applymask()" 
  ng-blur="isFocused = false; removemask()" 
  md-minlength="10" 
  md-maxlength="10" 
  name="SSN_{{$index}}" 
  ng-model="contact.contactDetails.attributeDetails.contact" 
  placeholder="Enter SSN"
  ng-value="!isFocused ? (contact.contactDetails.attributeDetails.contact | ssnMask) : contact.contactDetails.attributeDetails.contact"
>

TypeScript部分:

// 标记输入框是否处于聚焦状态
public isFocused = false;
// 默认用编辑用的掩码
public uimaskpattern = "999-99-9999";

public applymask() {
  this.uimaskpattern = "999-99-9999";
}

public removemask() {
  this.uimaskpattern = "XXX-XX-9999";
}

几个要注意的小细节

  • 不管用哪种方法,都要保证模型里的SSN格式统一:要么存纯10位数字,要么存带-的11位字符串,不然切换掩码时很容易出问题。
  • 用方案一的话,一定要用临时变量存原始值,不然失焦修改后再聚焦,原始的SSN就找不回来了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:52:59