使用自定义验证和动态值的 Angular 表单

     2023-03-13     16

关键词:

【中文标题】使用自定义验证和动态值的 Angular 表单【英文标题】:Angular forms using custom validation and a dynamic value 【发布时间】:2021-04-25 01:21:21 【问题描述】:

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

表单级验证

这将在整个表单上产生错误,而不仅仅是那个控件

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;
  ;

此订阅设置 arrayOfStrings 的值。

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

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

我试图让这个验证以第二种方式工作,这样我就可以基于单个控件显示验证,而不是如果整个表单都有这个错误。有谁知道我如何传递这个值并保持最新?

我还在一个单独的帮助文件中包含验证函数,以便在整个应用程序中重复使用。

Here is an example

【问题讨论】:

【参考方案1】:

您的要求

从您的帖子看来,您似乎有以下愿望清单:

    外部验证功能(可在您的应用中重复使用)。 控制级别验证(以及,通过扩展,错误)而不是表单级别。 用于再次验证您的字段的动态值列表。

解决方案

以下内容是从您上面的问题中复制而来的:

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("call, apply and bind" section, here 的释义)。这(呵呵)意味着我们可以正常使用数组,每次调用验证函数时都使用最新的值。

如果你想减少这个调用的大小,你可以使用.bind(this) 函数Eliseo mentioned in his answer。它会使事情变得更难阅读,但肯定会缩短创建表单的样板。选择你的毒药。

旁注

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

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

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

【讨论】:

谢谢,这太棒了,完全符合我的要求。我还可以对个人和表单级别使用相同的验证功能。我实际上曾尝试过这一点,但我传入了 FormGroup 而不是 AbstractControl,当它不起作用时,我离开了它。【参考方案2】:

更新

我的错!你可以传递一个数组,一个数组是一个不可变的值。所以如果你有

  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))

你可以看到simple 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),绑定更改“范围”,参见例如this link

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))

【讨论】:

抱歉,拖了这么久才回复,我被分配了一个急需的任务,忘记了这个。不幸的是, bind(this) 没有帮助,我忘了提到我的验证函数在一个单独的帮助文件中,绑定 this 不起作用,除非我使用错误。我能想到的唯一方法是将这个和一个值的字符串作为参数传递,并在函数中将它命名为 self self['arrayOfStrings'] 我的错!,如果你传递给函数一个数组必须工作。查看我的更新答案

如何使用 Angular 重置自定义表单控件

】如何使用Angular重置自定义表单控件【英文标题】:HowcanIresetacustomformcontrolwithAngular【发布时间】:2018-11-0921:54:04【问题描述】:我有一个带有验证的自定义表单控件。我在其中使用了一个独立的FormControl来处理值和一些验证。... 查看详情

Angular 11 自定义 ISBN 验证器响应式表单

】Angular11自定义ISBN验证器响应式表单【英文标题】:Angular11CustomISBNValidatorReactiveForms【发布时间】:2022-01-2322:09:59【问题描述】:我正在对ISBN号码进行自定义验证,我已经拥有检查号码并完美运行的功能,可以通过控制台为我... 查看详情

如何使用 Angular + Spring + JSON 自定义登录/身份验证

】如何使用Angular+Spring+JSON自定义登录/身份验证【英文标题】:HowtocustomLogin/authenticatewithAngular+Spring+JSON【发布时间】:2020-11-2314:22:05【问题描述】:我有一个Angular7前端和Spring后端。我的目标是使用JSON表单进行自定义登录。计划... 查看详情

自定义 angular2 表单输入组件,在组件内具有两种方式绑定和验证

】自定义angular2表单输入组件,在组件内具有两种方式绑定和验证【英文标题】:Customangular2forminputcomponentwithtwowaybindingandvalidationinsideacomponent【发布时间】:2016-04-2101:10:03【问题描述】:有没有办法制作双向绑定输入组件,也可... 查看详情

验证不会传播到 Angular 中的自定义表单控件 ng-select

】验证不会传播到Angular中的自定义表单控件ng-select【英文标题】:ValidationisnotpropagatetoCustomFormControlng-selectinAngular【发布时间】:2020-06-1223:43:55【问题描述】:我在Angular9应用程序中使用带有自定义表单控件的反应式表单。我用... 查看详情

angular5+自定义表单验证器

Angular5+自定义表单验证器CustomValidators标签(空格分隔):Angular首先阐述一下遇到的问题:怎样实现“再次输入密码”的验证(两个controller值相等)(equalTo)怎样反向监听(先输入“再次输入密码”,后输入设置密码)解决思... 查看详情

Angular - 模板驱动的表单 - 控制器中的自定义验证器功能

】Angular-模板驱动的表单-控制器中的自定义验证器功能【英文标题】:Angular-Templatedrivenforms-customvalidatorfunctioninthecontroller【发布时间】:2019-03-2306:30:29【问题描述】:由于在ngModel中使用响应式表单是deprecatedinAngular6,并且我的项... 查看详情

Angular 反应式表单自定义控件异步验证

】Angular反应式表单自定义控件异步验证【英文标题】:Angularreactiveformcustomcontrolasyncvalidation【发布时间】:2020-04-0608:48:11【问题描述】:更新:异步验证问题已成功解决。但是初始验证状态还有另一个问题。查看最新答案。诀窍... 查看详情

angular自定义验证器添加入模板驱动表单

创建自定义验证器的命令nggeneratedirectiveforbidden-name(自定义床啊金验证器的名称)生成的文件内容import{Directive}from'@angular/core';@Directive({selector:'[appForbiddenName]'})exportclassForbiddenNameDirective{const 查看详情

自定义 Angular 4 验证器取决于动态值

】自定义Angular4验证器取决于动态值【英文标题】:CustomAngular4Validatordependsondynamicvalue【发布时间】:2018-12-2909:00:55【问题描述】:我必须创建一个自定义验证器validLocation&lt;input[(ngModel)]="search"(change)="searchLocation&quo... 查看详情

Angular 2 - 自定义表单控件 - 禁用

】Angular2-自定义表单控件-禁用【英文标题】:Angular2-CustomFormControl-Disable【发布时间】:2017-03-0223:33:00【问题描述】:我使用ControlValueAccessor创建了一个自定义控件,该控件由input[type=text]和一个日期选择器组成。当我在模板驱动... 查看详情

为啥这种带有动态输入值的表单验证不起作用?

...【发布时间】:2020-04-0218:21:03【问题描述】:刚开始练习angular...我已经制作了一个反应形式(在父组件中),其值由子组件动态填充。提交此表单时会保存空值,因为尽管值在输入字段中可见,但表单并未检测到这 查看详情

FormArray 字段的角度自定义验证(反应式表单)

...ray字段的角度自定义验证(反应式表单)【英文标题】:AngularcustomvalidationforFormArrayfields(ReactiveForm)【发布时间】:2022-01-0212:57:53【问题描述】:我是Angular新手,想了解如何为FormArray执行自定义字段验证?FormArray是动态的,您可... 查看详情

angular表单验证

Angular表单验证分为两种验证:1.内置验证(required,minlength等);2.自定义验证(正则表达式)。接下来我们用一个注册账号的demo来看一下这两种验证是如何实现的。项目界面一、内置验证其中账户名有required验证和最短长度验... 查看详情

使用angular自定义字段校验指令

Angular中,提供的表单验证不能用于所有应用场景,就需要创建自定义验证器,比如对IP、MAC的合法性校验这里是根据官网实例自定义MAC地址的正则校验,环境为Angular:7.2.0,NG-ZORRO:v7.0.0-rc3添加指令/shared/validator.directive.ts注册到... 查看详情

Angular 反应式表单自定义验证器。仅在选中复选框时启用验证

】Angular反应式表单自定义验证器。仅在选中复选框时启用验证【英文标题】:Angularreactiveformscustomvalidator.EnableValidationonlywhencheckboxchecked【发布时间】:2019-02-2110:27:50【问题描述】:我在验证仅标记的复选框时遇到问题。首先,... 查看详情

在提交 Angular4 时触发表单验证

】在提交Angular4时触发表单验证【英文标题】:TriggerformvalidationonSubmitAngular4【发布时间】:2018-01-0921:43:40【问题描述】:我使用Angular和ionic设计了一个模板驱动的表单,它具有一些自定义(onblur)验证。现在我喜欢在点击提交按... 查看详情

如何根据 Angular 2 中的自定义验证规则显示错误消息?

】如何根据Angular2中的自定义验证规则显示错误消息?【英文标题】:HowtodisplayerrormessagebasedoncustomvalidationrulesinAngular2?【发布时间】:2016-11-2817:59:35【问题描述】:我正在使用模板驱动的方法在Angular2中构建表单,并且我已经成... 查看详情