• angular11源码探索十三[表单基础篇二]


    statusChanges

    statusChanges: Observable

    每次验证的状态,参数 status

    new FormControl({value: '', disabled: true} 禁用也可以这样写
    

    当我们手动设置报错

     const login = new FormControl('someLogin');
          login.setErrors({
            notUnique: true
          });
    login.valid //false, 是否通过校验
    login.setValue('aaa')
    login.valid //true
    

    get查询方式

     profileForm: FormGroup = new FormGroup({
        address: new FormGroup({
          name1: new FormControl()
        })
      });
    this.profileForm.get('address.name1');
    this.profileForm.get(['address', 'name1']);
    两种形式等价
    

    getError/hasError 区别

    查找方式

    get('xxx')
    get('aaa.bbb')
    get(['aaa','bbb'])
    get(['aaa',0]) // 数字就是索引
    

    hasError 报错查找

        this.profileForm.get(['address','name1'])?.setErrors({aaa:true})// 设置报错
        console.log(this.profileForm.get(['address', 'name1'])?.hasError('aaa'));
    		等价
        console.log(this.profileForm?.hasError('aaa', ['address', 'name1']));// true
    

    源码

      getError(errorCode: string, path?: Array<string|number>|string): any {
        const control = path ? this.get(path) : this;
        return control && control.errors ? control.errors[errorCode] : null;
      }
    
      hasError(errorCode: string, path?: Array<string|number>|string): boolean {
        return !!this.getError(errorCode, path);
      }
    

    却别应该是返回类型不一样吧,而且两者本质上就是父子关系,

    上个小案例

     let aa = this.profileForm.get('firstName') as FormControl;
        aa.setErrors({'aaa': '333'});
        console.log(aa.getError('aaa'));// 333
        console.log(aa.hasError('aaa'));// true
    

    addControl 添加

      (this.profileForm.get('address') as FormGroup).addControl('newControl', new FormControl(''));
        this.profileForm.addControl('name1',new FormControl())
        console.log(this.profileForm.value);
    

    removeControl

        this.profileForm.removeControl('address')
    

    当删除或者增加的时候,页面没有生效,其实应该在OnInit 生命周期中添加

    ngModel双向绑定

    <input type="text" [(ngModel)]="sex" (ngModelChange)="changeA($event)">
    

    校验器

    pristine   为修改UI中的值,默认为true     干净
    dirty       修改过UI的值,默认为false     脏的   
    		两个的默认值时相反的
    touched     类似触碰,失去焦点,默认是false
    untouched  未接触,默认为true
    异步验证的时候,表单控件进入 pending状态,默认false,并使用它提供有关正在进行的验证操作的视觉反馈
    促发每一个子项是不是纯洁的
    .markAsDirty()   // pristine   dirty  一般用这个
    促发每一个子项touched是否动过
    .markAsTouched/
    有效性(就是是否禁用)
        VALID: 该控件通过了所有有效性检查。
    
        INVALID 该控件至少有一个有效性检查失败了。
    
        PENDING:该控件正在进行有效性检查,处于中间状态。
    
        DISABLED:该控件被禁用,豁免了有效性检查。
    是否通过校验
    .valid
    显示报错信息
    .errors
    

    一般第二个参数用于校验,给数组整体添加校验

    //第一个参数不能与aaa
    function simpleValidator(c: AbstractControl): ValidationErrors|null {
      //c.get([0]) 和 c.at(0) 类似
      return c.get([0])!.value === 'aaa' ? null : {'broken': true};
    }
    //第一个参数必须传
    function arrayRequiredValidator(c: AbstractControl): ValidationErrors|null {
      return Validators.required(c.get([0]) as AbstractControl);
    }
    
      this.nameArr.valueChanges.subscribe(res => {
          //是否通过校验
          console.log(this.nameArr.valid);
          // 报错信息
          console.log(this.nameArr.errors);
        })
    
    nameArr: FormArray = new FormArray([
        new FormControl('bb'),
      ],
        [simpleValidator,arrayRequiredValidator]
      )
    

    pending

    异步验证的时候,表单控件进入 pending状态,默认false,并使用它提供有关正在进行的验证操作的视觉反馈

    function arrayRequiredValidator(c: AbstractControl): ValidationErrors | null {
      return of({name1: true}).pipe(delay(500))
    }
    
     this.profileForm = new FormGroup({
          firstName: new FormControl('xxx', null!, arrayRequiredValidator),
     })
       let aa = this.profileForm.get('firstName') as FormControl;
        console.log(aa.pending);// true
        of(null).pipe(delay(1000)).subscribe(_ => {
          console.log(this.profileForm.get('lastName').pending);// false
    
        })
    

    markAsPending() 手动设置

        console.log(this.profileForm.get('lastName').pending);//true
        this.profileForm.get('lastName').markAsPending()
        console.log(this.profileForm.get('lastName').pending);// false
    
    	默认直属父级也会被修改为true
    		c = new FormControl('value');
    		g = new FormGroup({'one': c});
    		c.markAsPending();
    		g.pending	//true
    源码
      markAsPending(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
        (this as {status: string}).status = PENDING;
    
        if (opts.emitEvent !== false) {
          (this.statusChanges as EventEmitter<any>).emit(this.status);
        }
    
        if (this._parent && !opts.onlySelf) {
          this._parent.markAsPending(opts);
        }
      }
    

    校验器源码

    function isEmptyInputValue(value: any): boolean {
      // 这里我们不检查字符串,所以它也适用于数组
      return value == null || value.length === 0;
    }
    function hasValidLength(value: any): boolean {
      // 判断有值得
      return value != null && typeof value.length === 'number';
    }
    

    疑问为什么有时候可以写单个值,有时候写数组,因为他是第二个参数,多个就写数组,单个就直接写单个值就行了

    min
    最小值,输入number 比较大小
    const control = new FormControl(2, Validators.min(3))
    //actual 当前值
    console.log(control.errors); // {min: {min: 3, actual: 2}} 
    
    const control = new FormControl(16, Validators.max(15));
    console.log(control.errors); // {max: {max: 15, actual: 16}}
    可以用来限制min max的number 值
    

    上个源码吧

      static max(max: number): ValidatorFn {
        return (control: AbstractControl): ValidationErrors|null => {
          if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
            return null;  // 不要验证空值来允许可选控件
          }
          const value = parseFloat(control.value);
          // 不是NaN然后比较大小
          return !isNaN(value) && value > max ? {'max': {'max': max, 'actual': control.value}} : null;
        };
      }
    
  • 相关阅读:
    postgresql 简单入门
    自用 docker-compose
    前后端分离 开发环境通过CORS实现跨域联调
    导出 java.io.IOException: 权限不够
    mysql 数值与字符类型 长度梳理
    easyui input未设id导致的问题
    springmvc处理url请求步骤
    js中的变量提升(hoisting)
    auto semicolon insertion 自动分号补齐的坑
    $.ajax dataType设置为json 回调函数不执行
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14209535.html
Copyright © 2020-2023  润新知