zoukankan      html  css  js  c++  java
  • angular11源码探索十四[表单校验器]

    自带的限制条件

    Validators.required
    报错
    {'required': true}
    
    验证字段值是否为true
    Validators.requiredTrue
    {required: true}
    
    邮箱
    Validators.email
    {email: true}
    
    最小长度
    Validators.minLength(3)
    {minlength: {requiredLength: 3, actualLength: 2}}
    还可以直接在input使用
    <input minlength="5">
        
     最大长度
    Validators.maxLength(5)
    {maxlength: {requiredLength: 5, actualLength: 7}
     <input maxlength="5">
         
    正则
    Validators.pattern(/foo/) 
    {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}
     <input pattern="[a-zA-Z ]*"> 这个页也可以直接在页面使用
    

    自定过滤器

    //这个传参数的版本
    export function maxLength(maxLength: number): ValidatorFn {
        return (control: AbstractControl): ValidationErrors|null => {
          return hasValidLength(control.value) && control.value.length > maxLength ?
              {'maxlength': {'requiredLength': maxLength, 'actualLength': control.value.length}} :
              null;
        };
      }
    如果不传参数的话就是这样的
    这个自己编写的自定义的
    export type ValidationErrors = {
      [key: string]: any
    };
    export function (control: AbstractControl): ValidationErrors|null {
          return  control.value.length > maxLength ?
              {'maxlength': {'requiredLength': maxLength, 'actualLength': control.value.length}} :null;
        };
      }
    

    这里可以参考源码中的写法

    export interface Validator {
      /**
       这个是直接的
       */
      validate(control: AbstractControl): ValidationErrors|null;
    
      /**
    注册一个回调函数,当验证器输入改变时调用, 暂时没发现用处
       */
      registerOnValidatorChange?(fn: () => void): void;
    }
    

    管道的自定义指令的时候

    @Directive({
      selector: '[customValidator]',
      // 注册指令,然后页面使用  
      providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
    })
    class CustomValidatorDirective implements Validator {
      validate(control: AbstractControl): ValidationErrors|null {
        return {'custom': true};
      }
    }
    

    禁用清空错误

    const arr = new FormArray([new FormControl()], () => ({'expected': true}));
    arr.errors  // {'expected': true}
    arr.disable();
    arr.errors // null
    arr.enable(); //解除禁用,就继续报错
    

    但是当禁用的时候,重新给数组添加一个FormControl 也促发脏依赖更新,所以也会报错

    FomrBuilder

     fbForm: FormGroup;
     constructor(
        private  fb: FormBuilder
      ) {
        this.fbForm = this.fb.group({
          firstName: 'some value',
          login: ['some',[Validators.required]],
          //禁用
          should: {value: 'should', disabled: true},
          login:fb.control('',{updateOn:'blur'}),
        });
    
      this.fbForm = this.fb.group({
            firstName: 'some value',
          //第三个参数是异步校验器
            login: ['some', null,[this.asyncValidator1, this.asyncValidator2]],
            arrOne: this.fb.array(
              ['one', 'two'],
              null,
              [this.asyncValidator1, this.asyncValidator2]
            )
          }
        );
        console.log(this.fbForm.get('arrOne')?.errors);
        console.log(this.fbForm.get('login')?.errors);
    // {'async1': true, 'async2': true}
    

    FormControl 第二个参数配置的几种形式

    如果第一个参数,那么值主要看value的值,第二个参数还是校验
    const control = new FormControl({ value: 'n/a', disabled: true });
    const control = new FormControl('', Validators.required);
    const control = new FormControl('', {
         validators: Validators.required,// 校验器
        asyncValidators: myAsyncValidator,// 异步校验器
        updateOn: 'blur'// 校验方式
     });
    事件更新
    更新策略AbstractControl(表示控件自行更新的事件)。
    离开的时候,才会触发校验
    可能的值:'change'| 'blur'| 'submit' 默认值:'change'
    
    我们发现FormGroup, FormControl,FormArray 类似,第二个参数都可以这样写
     this.fbForm = this.fb.group({
            firstName: '',
           },{updateOn: 'blur',validators:this.addFn}
        );
     const a = new FormArray([new FormControl(), new FormControl()], {updateOn: 'blur'});
    const control = new FormControl('', { updateOn: 'blur' });
    const control = new FormControl('', { updateOn: 'submit' });
    ====
     addFn(control: AbstractControl) {
        //   更改了,触发事件是失去焦点促发
        if (control.dirty) {
          console.log(control.value);
          return {name1: true};
        }
      }   
    
      this.fbForm = this.fb.group({
            firstName: ['some value', {
              updateOn: 'blur',
              validators: [this.addFn]
            }],
           three:fb.array([
            'one','two'
           ])
      })
        console.log(this.fbForm.get(['three',1])?.value);// get 还能这样查
    

    设置校验

    setValidators
          const c = new FormControl(null);
    	//单个值
          c.setValidators(Validators.required);
    	// 多个值
          c.setValidators([Validators.minLength(5), Validators.required]);
    	// 清空校验器
         c.clearValidators();
    	//设置异步校验器
        c.setAsyncValidators(asyncValidator('expected'));
    	//多个异步校验器
        c.setAsyncValidators([asyncValidator('expected')]);
    
    

    异步校验器

    export function asyncValidator(expected: string, timeouts = {}): AsyncValidatorFn {
      return (control: AbstractControl) => {
        const timeout = (timeouts as any)[control.value] ?? 0;
        const result = control.value != expected ? {async: true} : null;
        return createValidationPromise(result, timeout);
      };
    }
    function createValidationPromise(
        result: ValidationErrors|null, timeout: number): Promise<ValidationErrors|null> {
      return new Promise(resolve => {
        if (timeout == 0) {
          resolve(result);
        } else {
          setTimeout(() => {
            resolve(result);
          }, timeout);
        }
      });
    }
    

    使用案例

    function asyncFnOne(c:string): AsyncValidatorFn {
      return (control: AbstractControl)=> {
        console.log(control.value);
        return of({name1:true})
      }
    }
    function asyncFnTwo(c:string): AsyncValidatorFn {
      return (control: AbstractControl)=> {
        console.log(control.value);
        return of({name2:true})
      }
    }  
    
    this.profileForm = new FormGroup({
          firstName: new FormControl(1, null!, 				[asyncFnOne('xxx'),asyncFnTwo('bbb')])
        });
       this.profileForm.get('firstName').asyncValidator(new FormControl(11))
          .subscribe(console.log);
        // {name1: true, name2: true}
    
  • 相关阅读:
    创意吃鱼法
    雅礼上课
    坏掉的项链Broken Necklace
    2018-04-02练习
    【11月12日】Hadoop架构
    【11月10日】Redis 主从复制技术
    【11月10日】Redis 缓存系统常见问题及解决方案
    【11月9日】Redis 持久化
    【11月7日】Redis核心对象和数据类型
    【11月7日】Redis简介
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14221708.html
Copyright © 2011-2022 走看看