Angular 2将参数传递给验证器函数

时间:2016-05-09 15:42:37

标签: typescript angular

我的formcomponent类中有一个数组,希望能够将该数组传递给验证器函数。在表单中添加多个验证器时,我使用的是Validators.compose函数。这只接受验证器函数的名称,而不接受任何要传递的参数。是否可以在“compose”函数中为函数调用添加参数?

export class ClientFormComponent
{
    clientForm: ControlGroup;
    npi: AbstractControl;
    name: AbstractControl;

    constructor(private _clientService: ClientService, _fb: FormBuilder) {
        this.clientForm = _fb.group({ 'name': ['', Validators.compose([Validators.required])], 'npi': ['', Validators.compose([Validators.required, npiNumValidator, Validators.maxLength(10), Validators.minLength(10)])]});
        this.name = this.clientForm.controls['name'];
        this.npi = this.clientForm.controls['npi'];
    }
    
    @Input() clientList;
    active = true;   
   
    onSubmit(value: Client) {
        this._clientService.addDeleteClient(value, true)
            .subscribe(
            client => this.clientList.push(client));        
    }    
}

function npiNumValidator(control: Control): { [s: string]: boolean } {
    if (isNaN(control.value)) {
        return { npiNAN: true };
    }
}

感谢您的帮助!

6 个答案:

答案 0 :(得分:8)

只需将其移至课程

即可
class NpiNumValicator {
  constructor(private someField: someType) {}

  npiNumValidator(control: Control): { [s: string]: boolean } {
    if (isNaN(control.value)) {
        return { npiNAN: true };
    }
  }
}

然后像

一样使用它
this.clientForm = _fb.group({ 'name': ['',
    Validators.compose([Validators.required])], 'npi': ['', 
    Validators.compose([Validators.required, 
        new NpiNumValidator(someArg).npiNumValidator, 
        Validators.maxLength(10), Validators.minLength(10)
    ])
]});

可以在this中使用npiNumValidator,您可以使用

var npiNumVal = new NpiNumValidator(someArg);
this.clientForm = _fb.group({ 'name': ['',
    Validators.compose([Validators.required])], 'npi': ['', 
    Validators.compose([Validators.required, 
        npiNumVal.npiNumValidator.bind(npiNumVal), 
        Validators.maxLength(10), Validators.minLength(10)
    ])
]}); 

答案 1 :(得分:8)

  

是否可以在函数调用中添加参数   "构成"功能

确认者声明: straight out of Angular Code

/* Validator that requires controls to have a value of a minimum length. */

static minLength(minLength: number): ValidatorFn {
    return (control: modelModule.AbstractControl): {[key: string]: any} => {
      if (isPresent(Validators.required(control))) return null;
      var v: string = control.value;
      return v.length < minLength ?
                 {"minlength": {"requiredLength": minLength, "actualLength": v.length}} :
                 null;
    };
  }

用法:

Validators.compose([Validators.minLength(4)]

注意:要更好地了解它,请参阅How do JavaScript closures work?

答案 2 :(得分:3)

您还可以利用组件的方法来创建验证功能。这样,您就可以使用箭头功能访问该组件的属性。

以下是一个示例:

@Component({ ... })
export class MyComponent {
  constructor(private fb:FormBuilder) {
    this.form = this.fb.group({
      fieldName: [ '', this.createValidator() ]
    });
  }

  createValidator() {
    return (control) =>  {
      var arr = this.arr;
      (...)
    };
  }
}

答案 3 :(得分:3)

在某些情况下,需要传递给验证程序的数据是动态的,可以在调用验证程序的类中找到。在那些实例中,我只是在添加验证器时使用了“bind(this)”。 这是一个formBuilder示例:

this.profileFormGroups.push( this.formBuilder.group({
    name: [profile.name,
            Validators.compose([
              Validators.required,
              Validators.maxLength(30),
              Validators.pattern('[a-zA-Z ]*')
              ]),
            this.myNameValidator.bind(this)
          ]
  }) );
}, this);

然后在验证器中引用动态参数:

//我的异步验证器

myNameValidator(control: FormControl): any {
  let vm = this;

  return new Promise(resolve => {
   if ( vm.mydynamicvalue === control.name ) { ... }
      resolve({"Invalid User":true});
   else
      resolve(null)
  });

}

答案 4 :(得分:0)

最重要的答案意味着我将不得不为每个我不喜欢的验证器创建一个类。这是我的方法:

public static npiNumValidator(
    x: any
  ): (AbstractControl) => ValidationErrors | null {
    return (control: AbstractControl): ValidationErrors | null => {
      return !!x ? null : { error: true};
    };
}

用作:

this.form = this.formBuilder.group({
   email: [undefined, [ClassName.npiNumValidator('value')]],
});

答案 5 :(得分:0)

如果您需要从类中引用动态数据,您可以在参数中传递一个对象,而不是一个原语。

示例:

  valParams = {
    gte: 10
  }
  constructor(protected _fb:FormBuilder) { 
    this.numForm = _fb.group({
      num: ['', gte(this.valParams)]
    });
  }

验证函数:

export function gte(valParams: {gte:number}): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    let val: number = +control.value;
 
    if (isNaN(val)) return { 'gte': true }   
    if (val <= +valParams.gte) return { 'gte': true }

    return null;
  }
}

由于您传递的是对象,因此 JavaScript 将引用内存中的对象,而不是不可变的原语。

PS:作为奖励,因为您传递了对象引用,您可以直接从验证函数更新对象,然后组件类可以读取该对象。