Angular - FormArray 中的唯一性验证器

2023-11-24

我创建了一个自定义验证器来验证我的唯一性FormArray。我想在特定值已在数组中时显示错误。

问题是它没有按预期工作。

实际行为:

重现步骤:

  • 添加 3 个“输入”——地址;
  • 填写输入1;
  • 用不同的值填充输入2;
  • 将输入 3 填充为与输入 1 相同的值; (输入 1 和输入 3 均未出现错误)

预期行为:

如果“X 组”中出现相同的值,则其特定输入必须显示错误。

在上述情况下,错误应出现在输入 1 和 3 上。

假设我有 4 个输入:

  1. 值:堆栈
  2. 值:溢出
  3. 值:堆栈
  4. 值:溢出

4 个输入必须显示错误,因为它们都是重复的。


static uniqueBy = (field: string, caseSensitive = true): ValidatorFn => {
  return (formArray: FormArray): { [key: string]: boolean } => {
    const controls = formArray.controls.filter(formGroup => {
      return isPresent(formGroup.get(field).value);
    });
    const uniqueObj = { uniqueBy: true };
    let found = false;

    if (controls.length > 1) {
      for (let i = 0; i < controls.length; i++) {
        const formGroup = controls[i];
        const mainControl = formGroup.get(field);
        const val = mainControl.value;    
        const mainValue = caseSensitive ? val.toLowerCase() :  val;

        controls.forEach((group, index) => {
          if (i === index) {
            // Same group
            return;
          }

          const currControl = group.get(field);
          const tempValue = currControl.value;
          const currValue = caseSensitive ? tempValue.toLowerCase() : tempValue;
          let newErrors;

          if ( mainValue === currValue) {
            if (isBlank(currControl.errors)) {
              newErrors = uniqueObj;
            } else {
              newErrors = Object.assign(currControl.errors, uniqueObj);
            }

            found = true;
          } else {
            newErrors = currControl.errors;

            if (isPresent(newErrors)) {
              // delete uniqueBy error
              delete newErrors['uniqueBy'];

              if (isBlank(newErrors)) {
                // {} to undefined/null
                newErrors = null;
              }
            }
          }

          // Add specific errors based on condition
          currControl.setErrors(newErrors);
        });
      }

      if (found) {
        // Set errors to whole formArray
        return uniqueObj;
      }
    }

    // Clean errors
    return null;
  };
}

You can check it here DEMO.


在您的代码中使用嵌套 for 循环,在其中交错错误。

以下是每次迭代的验证状态:

  0      [null, "{"uniqueBy":true}", null]

  1      ["{"uniqueBy":true}", "{"uniqueBy":true}", null]

  2      [null, "{}", null]

http://plnkr.co/edit/MTjzQ9KiJHJ56DVAZ155?p=preview(添加三个地址并观察输出)

在下面的代码中,我在 for 循环语句之前仅清除一次错误,并且不再删除错误。

controls.map(formGroup => formGroup.get(field)).forEach(x => x.errors && delete x.errors['uniqueBy']);
for (let i: number = 0; i < controls.length; i++) {
    const formGroup: FormGroup = controls[i] as FormGroup;
    const mainControl: AbstractControl = formGroup.get(field);
    const val: string = mainControl.value;

    const mainValue: string = caseSensitive ? val.toLowerCase() :  val;
    controls.forEach((group: FormGroup, index: number) => {
        if (i === index) {
            return;
        }

        const currControl: any = group.get(field);
        const tempValue: string = currControl.value;
        const currValue: string = caseSensitive ? tempValue.toLowerCase() : tempValue;
        let newErrors: any;

        if ( mainValue === currValue) {
            if (isBlank(currControl.errors)) {
                newErrors = uniqueObj;
            } else {
                newErrors = Object.assign(currControl.errors, uniqueObj);
            }
            currControl.setErrors(newErrors);
            find = true;
        }
    });
}

笨蛋的例子

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular - FormArray 中的唯一性验证器 的相关文章

随机推荐

  • 如果字符串包含单词列表中的任何一个,R 每行返回 true 或 false

    我有一个包含一列字符串的数据集 text lt c flight cancelled dog cat coach travel car bus cow sheep high bar transport lt 0 df lt data fra
  • C 或 C++ 中的大整数 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我正在开发一个阶乘程序 当试图找到 1000 的阶乘时 该程序不起作用 我认为大整数是解
  • 在 PHP 中动态填充静态变量

    我有两个静态值 type 和 typeID 类型是人类可读的且恒定的 并且需要根据类型的值从数据库中查找类型ID 我需要在首次加载类定义时进行一次查找 为了说明这一点 这里有一些代码不起作用 因为您无法在声明空间中调用函数 MyClass
  • 从 s3 读取时出现溢出错误 - 有符号整数大于最大值

    使用以下代码将大文件从 S3 gt 5GB 读取到 lambda 中 import json import boto3 s3 boto3 client s3 def lambda handler event context response
  • 如何强制 ADO.Net 在阅读器 TableSchema 中仅使用 System.String 数据类型

    我正在使用 OleDbConnection 查询 Excel 2007 电子表格 我想强制 OleDbDataReader 仅使用字符串作为列数据类型 系统正在查看前 8 行数据并推断数据类型为 Double 问题是 在第 9 行 该列中有
  • memcpy memmove GLIBC_2.14/2.2.5 的解释

    我的问题源于一个共享库 我没有选择重新编译该库 错误指出undefined reference to memcpy GLIBC 2 14 我机器上的 GLIBC 版本是 2 12 我已经看到人们使用该行在线完成的修复 asm symver
  • 获取该月的最后一天

    有没有一种方法可以使用Python的标准库轻松确定 即一个函数调用 给定月份的最后一天 如果标准库不支持 那么 dateutil 包是否支持 calendar monthrange提供以下信息 日历 月份范围 年 月 返回指定月份的第一天的
  • Git 在 Mac / OSX 上非常慢

    每当我在 Macbook 配备 El Capitan 的全新 Macbook Pro 上使用任何与 Git 相关的内容时 每个命令几乎需要一分钟的时间 我做了一个简单的 GIT TRACE 1 git 存储 并得到了这个 17 04 27
  • Xcode 的“po”无法识别我想要研究的变量。为什么?

    环境 Xcode 6 Beta 4我试图仅使用以下命令来查看文本值 调试器 然而 调试器无法识别静态变量 通过 Let 对于 var 来说也是如此 Why func textFieldShouldReturn textField UITex
  • 用于测量解决方案/项目所花费时间的 Visual Studio 插件 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 有谁知道有一个 Visual Studio 2008 插件可以尝试跟踪您在任何给定解决方案或项目上花费的时间 我意识到这会很困难 就像在工作中我可能
  • 如何使用 PHP 进行倒计时

    我正在为我兄弟的婚礼创建一个网站 到目前为止一切进展顺利 然而 他希望在主页上显示婚礼倒计时 距离婚礼还剩下 X 个月 X 天 X 小时 我更愿意使用 php 来完成此操作 但也愿意接受其他建议 如果您可以帮助我提供编码想法 或者只是向我指
  • NSInvalidUnarchiveOperationException 无法解码 Apple Watch 扩展中的对象错误

    我有一个用户对象 需要将其存储在 NSUserDefaults 中并与 iOS 8 扩展应用程序 Watchkit 共享 在主容器应用程序中 我可以毫无问题地对对象进行编码和解码 但是 当我尝试检索扩展中存储的用户对象时 我得到了 NSIn
  • 联合供稿内容:已编码

    我正在使用SyndicationFeed类来消耗一些 RSS 提要 我想知道如何获得content encodedRSS 提要的节点 这是我正在使用的代码 XmlReader reader XmlReader Create response
  • 使用位移位除以 2 的幂

    我有以下任务 Compute x 2 n for 0 lt n lt 30使用位移位 要求 向零舍入 例子 divpwr2 15 1 7 divpwr2 33 4 2 合法经营者 lt lt gt gt 操作员最大数量 15 这是我到目前为
  • 使用 ffmpeg 更新视频上的 PNG 叠加

    我正在尝试制作视频的 RTMP 流并在其上放置一些图形数据 我有一个命令可以创建我需要的输出 唯一的问题是 尽管 PNG 图像在渲染过程中在磁盘上更新 但在输出视频中 叠加层始终保持不变 我希望 ffmpeg 在每次更改时 或每分钟一次 从
  • PlatformException(sign_in_failed,com.google.android.gms.common.api.ApiException:10:,null)

    我搜索了整个互联网 尝试了所有可能的解决方案 但我仍然无法从我的 flutter 应用程序中使用 GoogleSignIn 登录 我尝试过的事情 1 添加SHA 1证书2 添加SHA 256证书3 填充 O Auth 屏幕4 在fireba
  • 在python中打开和关闭没有文件对象的文件

    使用文件对象打开和关闭文件 fp open ram txt w fp close 如果我们想在不使用文件对象的情况下打开和关闭文件 即 open ram txt w 我们需要写吗close poem txt 或写作close 还好吗 他们都
  • JetStream CSS 和 JS 无法正常工作并显示 @vite(['resources/css/app.css', 'resources/js/app.js'])

    我在 laravel 8 上安装了 livewire laravel mix 和 jetstream 但是 Jetsream 的 css 和 js 不起作用 并在标题中显示一条消息 vite resources css app css re
  • 如何判断一个点是在立方体内部还是外部?

    给定 3D 空间中具有 8 个顶点的立方体 我怎样才能确定myPoint是在立方体内部还是外部 cube 0 x0 y0 z0 cube 1 x1 y1 z1 cube 2 x2 y2 z2 cube 3 x3 y3 z3 cube 4 x
  • Angular - FormArray 中的唯一性验证器

    我创建了一个自定义验证器来验证我的唯一性FormArray 我想在特定值已在数组中时显示错误 问题是它没有按预期工作 实际行为 重现步骤 添加 3 个 输入 地址 填写输入1 用不同的值填充输入2 将输入 3 填充为与输入 1 相同的值 输