【问题标题】:Implement custom validator for trimming the input fields in angular 2?实现自定义验证器以修剪角度 2 中的输入字段?
【发布时间】:2017-08-10 11:08:01
【问题描述】:

我是 Angular 新手,我想实现一个自定义验证器,它可以修剪模型驱动方法表单的输入字段。我在实现中遇到了一些问题。当我使用 setValue() 设置值时 在验证器函数中将发生无限调用堆栈。所以请建议我如何更新表单值以及我想以我正在使用的方式使用验证器的另一件事。

验证器函数

 static trimSpace(c:AbstractControl) {
        console.log(c);
        let v= c.value.replace(/\s\s+/g, ' ');
        let valid=true;
        console.log(v.trim());
        c.setValue(v);
     return true ? null : {
      trimmed: true
     }
 } 

组件形式

 this.addressForm=this.fb.group({
     firstName:['',Validators.compose([Validators.required,TrimValidator.trimSpace])]});

【问题讨论】:

  • 给出的答案都不是非常通用的。我很想看看你是否找到了一个好的解决方案。

标签: javascript angular validation


【解决方案1】:

您不应在验证阶段更改值,否则您可能会获得无限的验证周期。

这一行

let v= c.value.replace(/\s\s+/g, ' '); 

应该被删除,并且您应该创建一个自定义管道,以便在模板中更改该值,然后再到达验证器逻辑。

https://angular.io/guide/pipes

【讨论】:

  • c.setValue(v) 导致错误。这意味着我必须实现管道而不是验证器
  • 验证器用于验证。管道用于转换值。
  • 但我想更改表单控件的值,管道不用于更改 formControl 的值。
  • 我想将修剪后的数据发送到我的数据库。
【解决方案2】:

同意@Dean 但如果你仍然想这样做:

  c.setValue(v,{emitEvent:false});

如果 emitEvent 为 true,此更改将导致 FormControl 上的 valueChanges 事件被发出。这默认为 true(因为它属于 updateValueAndValidity)。

但这是一个糟糕的主意。

一定要创建管道或指令。

【讨论】:

  • 还是不行。can管道会改变formcontrol的值。
【解决方案3】:

我会依靠这里的一个事件来控制行为。所以你可以在模板中做:

(keyup)="trim(addressForm.controls.firstName.value)"

在 TS 中:

trim(value) {
  let val = value.replace(/\s\s+/g, ' ');
  this.addressForm.controls.firstName.patchValue(val)
}

似乎您正在进行某种类型的验证。然后,您可以在需要时为表单设置自定义错误:

this.addressForm.setErrors({trimmed: true})

并删除它...

this.addressForm.setErrors(null)

并在模板中显示错误(如果存在):

*ngIf="addressForm.hasError('trimmed')"

【讨论】:

  • 我不想在 html 和组件中编写修剪代码。在您的情况下,我必须一次又一次地编写此代码。
  • 好吧,您现在已经提到这应该是“通用的”,因此答案基于手头的问题,这表明这只是一种情况。您应该始终清楚地陈述您的问题。
  • 好的先生,很抱歉给您带来不便。请提供解决方案。
  • 这是我使用指令link 制作的插件链接。但在指令中,我也必须在 html 中编写该指令,这不是一个很好的方法。所以这就是为什么我想使用验证器来实现它。
  • 嗯,我明白了。我只是想知道该指令是否不是最佳选择。至少目前我看不到如何摆脱循环。使用valueChanges 我们可以做到{emitEvent:false},但这在这里没有帮助,我试过了。我知道在这里使用 valueChanges 不是一个选项,因为它也不是通用的。唔。棘手的问题:)
【解决方案4】:

尝试以下方式:

在值更改事件中修剪并设置新值,每当您的值发生更改或设置时,验证器函数就会自动被调用。

进口声明

function trimSpace(trimmedVal: boolean): ValidatorFn {   
  return (control: AbstractControl): {[key: string]: any} => {
    if(trimmedVal){
      return true ? null : { trimmed: true }
    }
  }; 
 }

//Component

export class  {
let trimmed: boolean = false;

//  constructor(
ngOnInit(){
    this.addressForm = this.fb.group({
        firstName:['', Validators.compose([Validators.required, trimSpace(this.trimmed)])]
    });
    this.addressForm.valueChanges.subscribe(data => this.onValueChanged(data));
}
onValueChanged(data?: any) {
    // trim value code
    if(value == trimmed){
        this.trimmed = true;
        // set value in following way
        this.addressForm..controls['firstName'].setValue('trimmedValue');
    }
}  }

【讨论】:

  • 这不是通用方法,因为我必须在每个组件中实现 onValueChanged 方法。
  • 假设我在表单控件中有 5 个字段,那么我将如何更新表单控件。
  • 如果你愿意,你也可以对特定字段使用 valueChange:this.addressForm.controls['firstName'].valueChanges.subscribe(data => this.someFunction(data));
  • 我想做一个可以修剪输入字段的验证器,我们不需要在我们的组件中编写代码。我们只需要在 formbuilder 中描述我们的验证器名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 2018-10-22
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多