• angular11源码探索十五[表单值的设置修改触发]


    setValue/patchValue

    setValue(value: any, options: {
        onlySelf?: boolean,
        emitEvent?: boolean,
        emitModelToViewChange?: boolean,
        emitViewToModelChange?: boolean
      }
      patchValue(value: any, options: {
        onlySelf?: boolean,
        emitEvent?: boolean,
        emitModelToViewChange?: boolean,
        emitViewToModelChange?: boolean
      }
    `onlySelf`:默认为false, 当前修改,不更新父级
    `emitEvent`:为true(默认值)' statusChanges '和 'valueChanges'当控件值被更新时,observable会发出带有最新状态和值的事件。当为false时,不触发任何事件。
    `emitModelToViewChange`: 默认为true,每个更改都会触发一个'onChange'事件到更新视图。
    `emitViewToModelChange`: 默认为true,会触发`ngModelChange`事件
    
    patchValue 如果多填参数,将多被忽略掉
    

    resetValue

       const  c = new FormControl('initial value');
          c.reset({value: 'initial value', disabled: false});
    	c.value  // initial value
    

    value 和getRawValue

      fbForm: FormGroup; 
        constructor(
            private  fb: FormBuilder
          ) {
        this.fbForm = this.fb.group({
            firstName: '',
            login: fb.control({value:'aaa',disabled:true}),
          });
        console.log(this.fbForm.value);
            //{firstName: ""}  
        检索所有值,而不考虑禁用状态。
        console.log(this.fbForm.getRawValue());
       //{firstName: "", login: "aaa"}     
    

    disable/enable

     `onlySelf`:默认为false, 当前修改,不更新父级
    `emitEvent`:为true(默认值)' statusChanges '和 'valueChanges'当控件值被更新时,observable会发出带有最新状态和值的事件。当为false时,不触发任何事件。
    
     disable(opts: {onlySelf?: boolean, emitEvent?: boolean} = {})
     enable(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
    

    ts类型问题

        (this.fbForm.get('firstName') as FormControl).setValue('333');
        (<FormControl> (this.fbForm.get('firstName'))).setValue('333');
    	fg = new FormGroup({
            'c1': new FormControl('v1'),
            'group': new FormGroup({'c2': new FormControl('v2'), 'c3': new FormControl('v3')}),
            'array': new FormArray([new FormControl('v4'), new FormControl('v5')])
          });
        (fg.get('array') as FormArray).at(1).disable();
        formGroup.get('group') as FormGroup;
    

    markAllAsTouched()

    将控件及其所有后代控件标记为“已接触”。

      markAllAsTouched(): void {
        this.markAsTouched({onlySelf: true});
        this._forEachChild((control: AbstractControl) => control.markAllAsTouched());
      }
    
        const innerGroupFirstChildCtrl = innerGroup.get('c2') as FormControl;
        innerGroupFirstChildCtrl.touched //false
        formGroup.markAllAsTouched();
    	formGroup.touched //true
    

    markAsTouched()

     markAsTouched(opts: {onlySelf?: boolean} = {}): void {
        (this as {touched: boolean}).touched = true;
    
        if (this._parent && !opts.onlySelf) {
          this._parent.markAsTouched(opts);
        }
      }
    

    markAsDirty传参类似

    markAsDirty

      markAsDirty(opts: {onlySelf?: boolean} = {}): void {
        (this as {pristine: boolean}).pristine = false;
    
        if (this._parent && !opts.onlySelf) {
          this._parent.markAsDirty(opts);
        }
      }
      pristine [干净]   为修改UI中的值,默认为true 
      是不是蒙蔽了
       console.log(this.fbForm.dirty); [脏的]    // false
       this.fbForm.markAsDirty()
       console.log(this.fbForm.dirty);    // true
       this.fbForm.markAsDirty({onlySelf:true}) //仅当前控件修改
    						为false全部查找
    

    reset

    把所有属性变成null

    默认AbstractControl 是基类

    也就是 FormControlFormGroupFormArray 的基类。也就是都具有reset这个属性

    影响的属性,会把他们修改成默认

    untouched 未接触,默认为true
    touched  接触,默认为false
    pristine  干净的,默认为true
    dirty	   脏的,默认为false
    
    清空报错信息
    g.pristine // 默认的时候 true
    g.markAsDirty();
    g.pristine // false
    g.reset() //清空所有
    g.pristine //true
    

    当有脏的兄弟,不会影响兄弟的结果,但是会影响当前和子代

    const form = new FormGroup({'g': g, 'c3': c3});
    g.markAsDirty();
    c3.markAsDirty();
    form.pristine //false
    g.reset();
    form.pristine //false
    因为兄弟是脏的,所以清空当前的不会影响兄弟的结果
    

    源码

     onlySelf 是否让父级知道修改,默认false,就是让父级知道
     emitEvent 是否触发statusChanges, valueChanges
    reset(value: any = {}, options: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
        this._forEachChild((control: AbstractControl, name: string) => {
          control.reset(value[name], {onlySelf: true, emitEvent: options.emitEvent});
        });
        this._updatePristine(options);
        this._updateTouched(options);
        this.updateValueAndValidity(options);
      }
    

    FormGroup.contains

    检查当前组内是否有具有给定名称的启用控件,返回是否启用[就是禁用的相反]

    人话就是查找子子属性是否解除禁用的状态,如果禁用就是false,没有禁用就是true

     contains(controlName: string): boolean {
        return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
      }
    

    css

    这个主要给input 添加class

    export const ngControlStatusHost = {
      '[class.ng-untouched]': 'ngClassUntouched', 没触摸
      '[class.ng-touched]': 'ngClassTouched',  触摸
      '[class.ng-pristine]': 'ngClassPristine',干净的
      '[class.ng-dirty]': 'ngClassDirty',     脏的
      '[class.ng-valid]': 'ngClassValid',    无效的
      '[class.ng-invalid]': 'ngClassInvalid', 有效的
      '[class.ng-pending]': 'ngClassPending', 进行中
    };
     * * ng-valid
     * * ng-invalid
     * * ng-pending
     * * ng-pristine
     * * ng-dirty
     * * ng-untouched
     * * ng-touched
    就是默认class里面有这些属性
    默认 class="ng-untouched ng-pristine ng-invalid"
    			没有触摸     干净的      如果没有设置校验就是通过校验的[就是有效的]
    当失去焦点就变成
    	['ng-invalid', 'ng-pristine', 'ng-touched']
    当设置值
    
    

    使用方法

    使用方法
      <div class="aaa">
        <input type="text" formControlName="firstName" class="bbb">
      </div>
    css使用
    .aaa .ng-dirty {
      border-left: 10px solid #42A948; /* green */
      background-color: red;
    }
    .bbb.ng-dirty{
      background-color: #d49d9d;
    }
    

    关于css的使用

    https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

    默认写的组件的css只适用本组件

    :host

    :host(.active) {
      border- 3px;
    }
    该:host选择是针对主机元素的唯一途径。您无法使用其他选择器从组件内部访问host元素,因为它不是组件自己的模板的一部分。host元素位于父组件的模板中。
    是把这个组件的大盒子作为目标,前提大盒子有这个class
    该:host-context()选择器的外观在组件**host元素**的**任何祖先**,直到文档根CSS类。:host-context()与其他选择器组合使用时,该选择器很有用。
    例如
    :host-context(.theme-light) h2 {
      background-color: #eef;
    }
    
    

    https://angular.io/guide/view-encapsulation

    考虑影子DOM解决css的问题

    页面上

    <hero-details _nghost-pmm-5>
      <h2 _ngcontent-pmm-5>Mister Fantastic</h2>
      <hero-team _ngcontent-pmm-5 _nghost-pmm-6>
        <h3 _ngcontent-pmm-6>Team</h3>
      </hero-team>
    </hero-detail>
    

    如果想深入了解影子组件可以看看我写的web组件的文章

    html 写法

      <input type="radio" formControlName="food" name="drink" value="chicken">
      <input type="radio" formControlName="food" name="drink" value="chicken12">
    
    <form [formGroup]="form">
          <div formArrayName="cities">
            <div *ngFor="let city of cityArray.controls; let i=index">
              <input [formControlName]="i">
            </div>
          </div>
    </form>
    ====
     <div [formGroup]="form">
          <div formArrayName="sex">
            <div *ngFor="let city of sex.controls; let i=index" [formGroupName]="i">
              <input formControlName="name1">
              <input formControlName="name2">
            </div>
          </div>
         </div>
    
      this.form = new FormGroup({
          sex: new FormArray([
            new FormGroup({
              name1:new FormControl(''),
              name2:new FormControl(''),
            })
          ])
    
  • 相关阅读:
    springboot搭建环境访问Controller层返回404
    SpringMVC使用注解@RequestMapping映射请求
    Redis数据类型
    mysql小结
    将数据四舍五入到十位
    Repeated DNA Sequences
    Reverse Linked List II
    Shortest Palindrome
    Single Number
    Sort Colors
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14233298.html
Copyright © 2020-2023  润新知