Angular8的使用(十):使用FormGroup和ControlValueAccessor

1.使用FormGroup

1.1.环境

第一步,安装form,package.json:

"dependencies": {
    
    
	"@angular/forms": "~x.xx.xxx",
}

第二步:在module中引入:

import {
    
     FormsModule,ReactiveFormsModule } from '@angular/forms';
@NgModule({
    
    
imports: [
	ReactiveFormsModule,
    FormsModule,
    ...
]

1.2.创建实体类test.model.ts

export class Test {
    
    
	name: string;
	constructor(name: string){
    
    
		this.name = name ? name : '';
	}
}

1.3.创建form实体类,继承FormGroup

export class TestForm extends FormGroup {
    
    
	constructor(proDetails?: Partial<Test>) {
    
    
        super({
    
    
            name: new FormControl(proDetails ? (proDetails.name ? proDetails.name : '') : '')
        });
        this.init();
    }
    
    init(){
    
    
		this.reset();
		this.updateValidity();
	}

	/**
	    * 提供在页面初始化使用
	    */
	initForm(data: any){
    
    
		this.reset();
		this.get('name').setValue(data.name);//给表单中,name进行赋值
		this.get('name').setValidators([Validators.required]); // 给name设置校验条件,参数可以是单个条件,也可以是多个条件的数组。
		this.updateValidity();
	}

	/**
		* 提供最后提交时,获取所有表单的值的时候使用
		*/
	formHasValues() {
    
    
        return this.value;
    }

	/**
		*校验某个字段是否是必须字段
		*/
	public isFieldRequired(field: string) {
    
    
        this.updateValueAndValidity();
        return this.controls[field].errors && this.controls[field].errors.required && this.get(field).touched;
    }

	/**
		*更新校验条件
		*/
	updateValidity() {
    
    
        Object.keys(this.controls).forEach((key) => this.get(key).updateValueAndValidity());
    }
}

1.4.在组件中使用form

1.4.1.HTML代码

<div [formGroup]="testForm">
	<input  formControlName="name" >
</div>

1.4.2.ts代码

export class WorkScheduleEditComponent implements OnInit {
    
    
	testForm: TestForm; //引入1.3.创建的form
	ngOnInit() {
    
    
		this.testForm = new TestForm();
	}

	/**
		*该方法提供给外部使用,data示例:{"name":"111a"}
		*/
	useTheComponent(data: any) {
    
    
		this.testForm.initForm(data);
	}

	submit() {
    
    
		let data = this.testForm.formHasValues();//获取表单中的数据
		//还可以调用this.testForm.invalid,查看校验是否正常
		console.info(data);
	}
}

2.自定义组件如何使用FormGroup

这个时候自定义组件需要实现ControlValueAccessor接口。

2.1.自定义组件HTML

test.component.html

<div>
	<input [(ngModel)]="_value"/>
</div>

2.2.自定义组件ts

test.component.ts

import {
    
     Component, OnInit, Input, forwardRef } from '@angular/core';
import {
    
     NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

@Component({
    
    
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss'],
  providers: [{
    
    
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => DropdownUtilComponent),
    multi: true
  }]
})
export class TestComponent implements ControlValueAccessor, OnInit {
    
    
  disabled: boolean;
  onModelChange: Function = () => {
    
    };
  onModelTouched: Function = () => {
    
    };
  _value: number;
  get value(){
    
    
    return this._value;
  }
  set value(value: number) {
    
    
    this._value = value;
    // component 内部的值同步到 form model
    this.onModelChange(this._value);
  }

  /**
  	 * form model 的值同步到 component 内部
  	 */
  writeValue(obj: any): void {
    
    
    if (obj !== undefined) {
    
    
      this.value = obj;
    }
  }
  registerOnChange(fn: any): void {
    
    
    this.onModelChange = fn;
  }
  registerOnTouched(fn: any): void {
    
    
    this.onModelTouched = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    
    
    this.disabled = isDisabled;
  }
	
	/**
		*提供外部使用,修改value的值
		*/
	changeValue(value: any){
    
    
		this.value = value;
	}
}

writeValue,registerOnChange,registerOnTouched,setDisabledState为ControlValueAccessor接口需要去实现的方法。writeValue是进行赋值。

2.3.其他组件的form使用该组件

HTML

<div  [formGroup]="testForm">
	<app-test formControlName="test"></app-test>
</div>

TS的代码和1.4.2的代码一致

猜你喜欢

转载自blog.csdn.net/m0_37356874/article/details/108766588