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

基于性别校验身份证号的表单自定义验证器问题求助

问题分析与修正代码

你的表单需要根据选择的性别校验身份证号对应位的奇偶性,但现有代码存在几处关键错误:

  • 身份证号字符获取错误:通过nationalId[14]?.value获取字符的方式有误,nationalId是FormControl实例,需先取其value属性,再通过索引定位对应字符;且字符串索引从0开始,若要取第12位,对应索引应为11。
  • 校验逻辑错误:直接比较身份证号字符和性别值的逻辑不成立,需将身份证号对应位的字符转为数字,再根据性别判断其奇偶性是否匹配。

假设性别选择框sexId的取值规则为:男性对应1,女性对应2(若实际取值不同,可自行调整判断条件),修正后的校验器代码如下:

nationalIdValidator(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const nationalIdCtrl = control.get('nationalId');
    const sexCtrl = control.get('sexId');

    // 任一控件未初始化或无值时,不触发校验
    if (!nationalIdCtrl || !sexCtrl || !nationalIdCtrl.value || !sexCtrl.value) {
      return null;
    }

    const nationalId = nationalIdCtrl.value.trim();
    const sexValue = sexCtrl.value;

    // 可选:校验身份证号长度是否合规
    if (nationalId.length !== 18) {
      return { 
        'nationalId not valid': { 
          'id': nationalId, 
          'reason': '身份证号长度不正确' 
        } 
      };
    }

    // 获取第12位字符并转为数字
    const genderDigit = parseInt(nationalId[11], 10);
    if (isNaN(genderDigit)) {
      return { 
        'nationalId not valid': { 
          'id': nationalId, 
          'reason': '身份证号包含非数字字符' 
        } 
      };
    }

    // 根据性别判断奇偶性是否匹配
    const isMale = sexValue === 1;
    const isValid = isMale ? (genderDigit % 2 === 1) : (genderDigit % 2 === 0);

    return isValid ? null : { 
      'nationalId not valid': { 
        'id': nationalId, 
        'sex': sexValue,
        'reason': `身份证号第12位应为${isMale ? '奇数' : '偶数'}`
      } 
    };
  };
}

关键修正说明

  • 正确获取身份证号对应位的字符,并转为数字进行奇偶判断
  • 新增身份证号长度、数字格式的基础校验(可根据实际需求移除或调整)
  • 明确性别值与奇偶性的对应逻辑,提升代码可读性
  • 错误信息补充具体原因,便于用户理解校验失败的问题点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:25:27