当前位置: 首页 > 知识库问答 >
问题:

使用自定义验证和动态值的角度形式

贾飞鸿
2023-03-14

我正在尝试创建一个定制的反应式表单验证,它允许我传递一个数据数组来检查字符串是否已经存在。我可以用一种方法进行验证,因此这将是一个表单级验证,但我无法让它在单个表单控件上工作。

这将在整个窗体上创建错误,而不仅仅是控件

this.myForm = this.fb.group({
  name: ['', Validators.compose([
    Validators.required,
  ]),
  ],
}, {
  validator: (formGroup: FormGroup) => this.checkStringExists(
    formGroup.controls.name,
    this.arrayOfStrings,
  ),
});

定义验证,允许我接收表单控件并根据传入的数组检查它。

checkStringExists(formInput: AbstractControl, names: string[]): { [s: string]: boolean } {
  if (names && names.length && formInput && formInput.value) {
    const isUnique = !names.find((name) => name === formInput);
    if (isUnique) {
      return { nameExists: true };
    }
  }
  return null;
}

这将仅在特定控件上创建错误

this.myForm = this.fb.group({
  name: ['', Validators.compose([
    Validators.required,
    this.checkStringExists(this.arrayOfStrings),
  ]),
  ],
});

定义验证,允许我只将数组作为Validators.compose[]的一部分

checkStringExists(names: string[]): ValidatorFn {
  return (formInput: AbstractControl): ValidationErrors | null => {
    if (names && names.length && formInput && formInput.value) {
      const isUnique = !names.find((name) => name === formInput);
      if (!isUnique) {
        return { nameExists: true };
      }
    }
    return null;
  };
}

此订阅设置ArrayOfString的值。

mySubscription.subscribe((value: string[]) => {
    this.arrayOfStrings = value;
  })

我的问题是ArrayOfString可能会更新多次。如果我以第一种方式使用验证,则ArrayOfString是最新的。如果以第二种方式使用验证,ArrayOfString为null/初始值。

我正在尝试以第二种方式进行验证,这样我就可以基于单个控件显示验证,而不是在整个表单都有此错误的情况下。有人知道我如何传递此值并使其保持最新吗?

我也有一个单独的辅助文件中的验证功能,用于整个应用程序的可重用性。

这里有一个例子

共有2个答案

鲜于德泽
2023-03-14

使现代化

我的坏!你可以传递一个数组,数组是一个不可变的值

  export function findArray(array){
    return (control=>{
      return array.indexOf(control.value)<0?{error:'not match'}:null
    })
  }

  array=['one','two']
  control=new FormControl(null,findArray(this.array))

你可以看到一个简单的stackblitz

实际上,验证器不能有“动态”参数。所以有些人喜欢

foolValidator(name:string)
{
   return (control:AbstractControl)=>{
        return control.value!=name?{error:'it's not the name'}:null
   }
}
name="joe"
control=new FormControl(null,foolValidator(this.name))

只考虑“joe”,而不是变量“name”的名称

您可以使用bind(this),bind更改范围,例如参见此链接

foolValidator() //see that you not pass the argument
{
   return (control:AbstractControl)=>{
        //see that you use "this.name"
        return control.value!=this.name?{error:'it's not the name'}:null
   }
}
name="joe"
control=new FormControl(null,foolValidator().bind(this))
濮阳原
2023-03-14

从你的帖子中,你似乎有以下愿望清单:

  1. 外部验证功能(用于整个应用程序的可重用性)。
  2. 而不是在表单级别进行控制级别验证(以及扩展的错误)。
  3. 用于再次验证字段的动态值列表。

以下内容摘自您的上述问题:

checkStringExists(formInput: AbstractControl, names: string[]): { [s: string]: boolean } {
  if (names && names.length && formInput && formInput.value) {
    const isUnique = !names.find((name) => name === formInput);
    if (isUnique) {
      return { nameExists: true };
    }
  }
  return null;
}

你可以在字段级别使用它,而不是在表单的验证器部分使用它,就像这样:

// Contents could change later!
arrayOfStrings: string[] = [];

...

this.individualControlForm = this.fb.group({
  name: ['', Validators.compose([
    Validators.required,
    (control: AbstractControl) => ValidationHelper.checkStringExists(
          control, this.arrayOfStrings
    )]),
  ],
});

因为我们使用箭头函数作为我们的验证函数,所以我们从函数定义的范围继承了this(此处是调用、应用和绑定部分的释义)。这意味着我们可以正常使用数组,每次调用验证函数时都使用最新的值。

如果您想减少此呼叫的大小,可以使用Eliseo在回答中提到的.bind(this)函数。它可以使事情更难阅读,但肯定会缩短创建表单的样板。选择你的毒药。

如果您确实需要使用整个表单验证(例如,如果需要考虑多个字段来决定单个字段是否有效),但希望错误显示在字段上,则可以使用

formData.form.controls['email'].setErrors({'incorrect': true});

手动设置该特定字段(源)上的错误。

 类似资料:
  • 我有一个表单,它要求两个字段中至少有一个字段具有值才能有效。现在,我已经构建了一个指令“KeywordandAuthor”来处理此验证。我已经成功地让它正确地检查任何一个字段是否有值,如果有,则将验证设置为true。我不确定如何将其他字段的验证设置为true。以下是指令的当前代码: 如何将siblingElem的有效性设置为true? **编辑** 这是我想要的工作解决方案。 要实现的关键点是,n

  • 问题内容: 具有角形的这种普通(名称属性由服务器要求)形式,无法弄清楚如何使验证有效。我应该在ng-show =“ TODO”中添加什么 http://jsfiddle.net/Xk3VB/7/ ps:这只是一种形式,更复杂 谢谢 问题答案: AngularJS依靠输入名称来暴露验证错误。 不幸的是,到目前为止,不可能(不使用自定义指令)动态生成输入的名称。确实,检查输入文档,我们可以看到name

  • 本文向大家介绍Android动态自定义圆形进度条,包括了Android动态自定义圆形进度条的使用技巧和注意事项,需要的朋友参考一下 效果图: A.绘制圆环,圆弧,文本 B.自定义属性的具体步骤 具体步骤: 1. 定义属性: 在values目录下创建attrs.xml 2. 在布局文件中引用当前应用的名称空间 3. 在自定义视图标签中使用自定义属性 4. 在自定义View类的构造方法中, 取出布局中

  • 我有一个名为的自定义验证器函数。 如果我像这样设置表单,一切都工作了: 但是,如果我使用这样的表单生成器设置表单: 如果构造函数中将定义为,则验证不起作用。所谓“不工作”,我的意思是表单的valid属性不正确,在控制台中我看不到预期的输出(使用第一个方法显示)。 我没有在第二个方法中正确定义验证器(如果是这样的话,应该如何定义它),或者FormBuilder有什么东西使自定义验证器不可用?

  • 表单验证发生在数据验证之后。如果你需要定制化这个过程,有几个不同的地方可以修改,每个地方的目的不一样。表单处理过程中要运行三种类别的验证方法。它们通常在你调用表单的is_valid() 方法时执行。还有其它方法可以触发验证过程(访问errors 属性或直接调用full_clean() ),但是通用情况下不需要。 一般情况下,如果处理的数据有问题,每个类别的验证方法都会引发ValidationErr

  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe