ng4 自定义表单组件

自定义表单组件分为单值组件和多值组件.

单值组件:input/select/radio/textarea

多值组件:checkbox/tree组件

大环境:

1.必须实现ControlValueAccessor接口

不同输入控件的数据更新方式不一样。

比如input是设置value值,而checkbox是设置checked属性。

因此不同类型的输入控件都有一个ControlValueAccessor来更新视图

export interface  ControlValueAccessor{
     writeVlaue(obj:any) :void;             //model->view
     registerOnchange(fn:any) :void;    //view->model
     registerOnTouched(fn:any):void;
     setDisabledState?( isDisabled:boolean):void
}


//实现
get value():any{
    return this.innerVal;
}

set value(value){
  this.innerVal=value
}

writeValue(value:any){
   if(value!=this.innerVal){
       this.innerVal=value;
   }
}

2.必须注册成为表单组件(使用providers属性)

@Component({
  selector:'nw-input',
  templateUrl:'./nw-input.component.html',
  styleUrls:'./nw-input.component.scss',
  providers:[
      provide:NG_VALUE_ACCESSOR,                    //将组件注册到DI框架,让其成为一个可被表单访问的组件
      useExisting:forwardRef(()=>NwInputComponent), //让组件暴露对应的validatate方法实现表单验证
      multi:true                                 //表示这个token对应多个依赖项,可在多个表单里使用,互不影响
  ]
})

具体实现:

1.如果是单值表单组件,使用FormControl

//组件
export class NwSelectComponent implements ControlValueAccessor{
    selectFormControl:FormControl;

    getControl(vfn:ValidatorFn[]):FormControl{
      if(!this.selectFormControl){
           this.selectFormControl=new FormControl('',vfn)
      }
     return this.selectFormControl
   }
}
//使用

thatForm:formGroup;
@ViewChild('xxComp')
xxComp:NwSelectComponent;

this.thatForm=this.formBuilder.group({
  xx:this.xxComp.getControl([Validator.required,Validators.minLength(5)])   //验证条件还是数组
})

2.如果是多值表单组件,使用FormArray

//组件
export class NwCheckboxGroupComponent implements ControlValueAccess{
    checkboxFormArray:FormArray=new FormArray([]);

    getControls(vfn:ValidatorFn):FormArray{
     if(!this.checkboxkFormArray){
        this.checkboxFormArray=new FormArray([],vfn);
    }
   }
    cleanControls(){
      while(this.checkboxFormArray.controls.length!==0){
           this.checkboxFormArray.removeAt(0) 
     }
   pushControl(id:any){
      this.checkboxFormArray.push(new FormControl(id))
   }
 }
}
//使用
thatForm:FormGroup;
@ViewChild(xxComp)
xxComp:NwCheckboxGroupComponent;

this.thatFom=this.formBuilder.group({
    xx:this.xxComp.getControls(Valitators.required)  //验证条件不再允许数组了
})    

猜你喜欢

转载自www.cnblogs.com/artimis/p/9020776.html
今日推荐