zoukankan      html  css  js  c++  java
  • angular13源码分析(表单查缺补漏一)

    QQ20220113140932.png

    FormControl

    
      maxLength(): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
          // 给个报错信息
          if (control.value === '333') {
            return {sex: true};
          }
          return null;
        };
      }
      sex: FormControl = new FormControl({value: '111', disabled: false}, [this.maxLength()]);
    
    <input type="text" [formControl]="sex">
    

    getError 与hasError

    返回类型不一样
    getError :any
    hasError :boolean
    
      formModel!: FormGroup;
         ngOnInit(): void {
            this.formModel = new FormGroup({
              login: new FormControl('', [this.maxLength()]),
              passwords: new FormGroup({
                password: new FormControl()
              })
            });
    
            console.log(this.formModel.getError('sex', ['login']))
          }
          this.validateForm.getError('required', ['sex'])
    	  this.validateForm.get('sex')!.getError('required')
          this.validateForm.getError('required',['loginGroup','add1'])
    	  this.validateForm.getError('required','loginGroup.add1')
    

    getError/hasError 第二个参数可以是一个数组, 进行属性查询

    updateValueAndValidity

    重新计算控件的值和验证状态。

    onlySelf: 当为true时,只自身被触发但是父级不会被触发。当为false或未提供时,更新所有直接的祖先。默认是false

    emitEvent: 默认为truestatusChangesvalueChanges可观察对象都会在控件更新时发出带有最新状态和值的事件。当为false时,不触发任何事件。

          this.form.updateValueAndValidity({emitEvent: false});
    

    get

        get(path: Array<string | number> | string): AbstractControl | null;
    this.form.get('xxx')!.value
    this.form.get(['aaa','bbb'])!.value
    this.form.get('aaa.bbb').value    // 还可以这样拿值
    
    数组
     const g = new FormGroup({'array': new FormArray([new FormControl('111')])});
     g.get(['array', 0])!.value
     // 111
    

    设置报错信息

    setErrors

    control.get('timeEnd').setErrors(null);
    control.setErrors({required: true});
    // 查看报错信息
    this.formModel.get('login')!.errors
    

    array-insert

    FormArray 数组中,索引插入一个

        this.formModel = new FormGroup({
          sexArr: new FormArray([])
        });
        const arr=this.formModel.get('sexArr') as FormArray;
        arr.push(new FormControl(1))
        arr.push(new FormControl(2))
        arr.insert(1,new FormControl(3))
        // [1, 3, 2]
    
    插入的时候, 第二个参数也可以添加配置
          a.push(c1, {emitEvent: false});
    

    setControl

    arr.push(new FormControl(1))
    arr.push(new FormControl(2))
    arr.setControl(1,new FormControl(4))
    // [1,4]
    this.formModel.setControl('login',new FormControl('333'))
    // {login: '333'}
    

    异步校验器

      validatorFnOne = (value: any) => {
        console.log(value);
        return {controlsOne: true};
      };
      asyncValidatorFn = (value: any) => of(this.validatorFnOne(value));
    
    	this.formModel = new FormGroup({
          login: new FormControl('1212', null, this.asyncValidatorFn),
          sex1: ['', {
            updateOn: 'blur',
            validators: [
              (val: AbstractControl) => ({sexError: true})
            ]
          }],
        });
    

    getRawValue

    包括所有的值, 包括禁用的

      this.formModel = new FormGroup({
          login: new FormControl('111', null, this.asyncValidatorFn),
          loginOne: new FormControl('222'),
        });
        this.formModel?.get('loginOne')!.disable();
        console.log(this.formModel.value);
       // {login:111}
        console.log(this.formModel.getRawValue());
       // {login:111,loginOne:222}
    

    reset

    a.setValue(['new value', 'new value']);
    a.reset([{value: 'initial value', disabled: false}, '']);
    a.value
    //['initial value', '']
    this.validateForm.reset({sex:{value:'2232323',disabled:true}})
    

    reset() 执行,

    • 会保留之前的禁用状态
    • valueChangestatusChanges 会被执行

    pristine

    如果用户尚未更改 UI 中的值(默认为true)

    a.pristine  //true
    a.markAsDirty(); // 触发了, 或者输入改变值
    a.pristine  // false
    a.reset();  // 重置状态
    a.pristine  // true
    

    dirty

    是否更改了 UI 中的值

    pristine的值相反(默认是false)

    untouched

    如果控件未被标记为已触摸(默认为true)

    我们发现当我们失去焦点才会触发状态的修改blur或者markAsTouched()

    a.untouched  //true
    a.markAsTouched(); // 触发了, 或者输入改变值
    a.untouched  // false
    a.reset();  // 重置状态
    a.untouched  // true
    

    touched

    如果控件标记为 则为真touched

    untouched 相反

    报错的状态

    // 默认
    g.valid   // true
    g.errors  // null
    g.setErrors({required: true}) // 设置报错
    g.valid   // false
    g.errors  // {required: true}
    

    pending

    这个我还不清楚实用的点

    默认为false 校验的状态

    markAsPending(opts: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void
    c.markAsPending();
    c.pending   // true
    

    校验

    interface AbstractControlOptions {
        /**
         * @description
         * The list of validators applied to a control.
         */
        validators?: ValidatorFn | ValidatorFn[] | null;
        /**
         * @description
         * The list of async validators applied to control.
         */
        asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
        /**
         * @description
         * The event name for control to update upon.
         */
        updateOn?: 'change' | 'blur' | 'submit';
    }
    第二个,第三个
    validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
    asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
    

    status

    a.status   // VALID
    a.disabled // false
    
    a.disable();
    
    a.status   // DISABLED
    a.disabled // true
    
    a.enable();
    a.status   // VALID
    a.disabled // false
    

    FormBuilder

    export class ThreeControlComponent implements OnInit {
      validateForm!: FormGroup;
    
      constructor(private fb: FormBuilder) { }
      ngOnInit(): void {
            this.validateForm = this.fb.group({
              sex: ['111'],
              login: [{value: 'xxxxx', disabled: false}, this.validatorFn,this.asyncValidatorFn],
              a: this.fb.array([
                	    'one',
                        ['two', this.validatorFn, this.validatorFnOne],
                        {value: 'three', disabled: false},
                        [{value: 'four', disabled: false},this.validatorFn, this.validatorFnOne],
                        this.fb.control('xxx'),
                        this.fb.control({value:'xxx',disabled:false}),
         		 ])
            });
      }
    }
    

    updateOn 更新策略

    updateOn:FormHooks
    可能的值:'change'| 'blur'| 'submit' 默认值:'change'
    案例:
     this.validateForm = this.fb.group({
          sex1: ['', {updateOn: 'blur'}],
     })
    // 我们发现失去焦点的时候会触发
        this.validateForm.get('sex1')!.valueChanges.subscribe(console.log)
    // 查看当前的更新方式
    this.validateForm.get('sex1')!.updateOn
    // blur
    如果有更新策略,那么第二个参数
    {
        validators:[],
        asyncValidators:[],    
        updateOn:'blur'
    }
    

    setValidators/setAsyncValidators

    设置校验方式

     validatorFnOne = (value: any) => {
        // console.log(value);
        return {controlsOne: true};
      };
      asyncValidatorFn = (value: any) => of(this.validatorFnOne(value));
    
           this.validateForm.get('sex1')!.setValidators([Validators.required])
    
           this.validateForm.get('sex1')!.setAsyncValidators([this.asyncValidatorFn]);
    

    dirty

    当通过 UI 更改控件的值时,控件会变dirty , 默认为false

    this.validateForm.get('sex1')!.dirty   // false
    this.validateForm.get('sex1')!.markAsDirty();
    this.validateForm.get('sex1')!.dirty  // true
    
    windowDuration.invalid && (windowDuration.dirty || windowDuration.touched)
    

    addControl

        this.validateForm = this.fb.group({
          sex1: ['', {updateOn: 'blur'}],
        });
    this.validateForm.addControl('two1',new FormControl('1111'),{})
    

    removeControl

    this.validateForm.removeControl('sex')
    g.removeControl('two', {emitEvent: false});
    

    contains

    查看表单是否有这个控件,默认为false

    this.validateForm = this.fb.group({
          sex: ['111', [Validators.required]],
        });
    
        console.log(this.validateForm.contains('sex')); //true
    

    通过dom修改表单的值,触发更新

    <form [formGroup]="validateForm">
      <input type="text" formControlName="sex" #sex>
    </form>
    
    import {ɵgetDOM as getDOM} from '@angular/common';
    
    export class ThreeControlComponent implements OnInit, AfterViewInit {
        dispatchEvent(element: any, eventType: any): void {
            const evt: Event = getDOM().getDefaultDocument().createEvent('Event');
            evt.initEvent(eventType, true, true);
            getDOM().dispatchEvent(element, evt);
          }
    
      ngAfterViewInit() {
        this.sex.nativeElement.value='111111111';
        setTimeout(()=>{
          this.dispatchEvent(this.sex.nativeElement, 'input');
          console.log(this.validateForm.value);
        })
      }
    }
    

    本质是因为DOM的修改,不会触发脏检查, 需要通过自定义事件进行触发脏检查机制, 从而更新

    form表单完整版本

    <form [formGroup]="validateForm">
      <input type="text" formControlName="sex">
    <!--  对象集合-->
      <ng-container formGroupName="sexGroup">
        <input type="text" formControlName="sexOne">
      </ng-container>
    <!--  数组集合-->
      <ng-container formArrayName="sexArr">
        <ng-container *ngFor="let item of sexArrControl.controls;let index=index">
          <ng-container [formGroupName]="index">
            <input type="text" formControlName="sexOne">
            <input type="text" formControlName="sexTwo">
          </ng-container>
        </ng-container>
      </ng-container>
    </form>
    
    export class ThreeControlComponent implements OnInit, AfterViewInit, AfterContentInit {
      validateForm!: FormGroup;
      constructor(private fb: FormBuilder) { }
      ngOnInit(): void {
        this.validateForm = this.fb.group({
          sex: ['111'],
          sexGroup: this.fb.group({
            sexOne: ['222']
          }),
          sexArr: this.fb.array([])
        });
        this.sexArrControl.push(this.sexObj)
      }
    
      get sexObj(): FormGroup {
        return this.fb.group({
          sexOne: ['a'],
          sexTwo: ['b'],
        })
      }
    
      get sexArrControl(): FormArray {
        return this.validateForm.get('sexArr') as FormArray;
      }
    }
    

    决定自己的高度的是你的态度,而不是你的才能

    记得我们是终身初学者和学习者

    总有一天我也能成为大佬

  • 相关阅读:
    Linux命令(25)userdel命令
    Linux命令(24)clear命令
    Linux命令(23)usermod命令
    Linux命令(22)useradd命令
    c++primer 练习9.28
    概率论python代码
    python自写软件(三)
    Linux描述符表和描述符高速缓存
    操作系统的坑(更新)
    python自写软件(二)
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/15797414.html
Copyright © 2011-2022 走看看