Angular使用ControlValueAccessor创建自定义表单控件
在Angular自定义表单控件,有时你想要的输入不是标准的文本输入、选择或复选框。通过实现ControlValueAccessor接口并将组件注册为NG_VALUE_ACCESSOR,您可以将自定义表单控件无缝地集成到模板驱动或响应表单中,就像它是本地表单一样!
ControlValueAccessor
ControlValueAccessor是一个接口,充当AngularAPI和DOM元素之间的桥梁
ControlValueAccessor是一个连接表单模型和视图(DOM元素)的接口,自定义的表单控件必须实现这个接口,它的作用是:
- 把form模型中值映射到视图中
- 当视图发生变化时,通知formdirectives或formcontrols
Angular引入这个接口的原因是,不同的输入控件数据更新方式是不一样的。例如,对于我们常用的文本输入框来说,我们是设置它的value值,而对于复选框(checkbox)我们是设置它的checked属性。实际上,不同类型的输入控件都有一个ControlValueAccessor,用来更新视图
Angular中常见的ControlValueAccessor有:
- DefaultValueAccessor-用于text和textarea类型的输入控件
- SelectControlValueAccessor-用于select选择控件
- CheckboxControlValueAccessor-用于checkbox复选控件
exportinterfaceControlValueAccessor{ writeValue(obj:any):void registerOnChange(fn:any):void registerOnTouched(fn:any):void }
writeValue(obj:any)是将表单模型中的值写入视图中。
writeValue(value:any):void{ this._renderer.setProperty(this._elementRef.nativeElement,'value',value); }
registerOnChange(fn:any)是一个方法,用于注册在视图中的某些内容发生更改时应调用的处理程序。它获取一个函数,告诉其他表单指令和表单控件更新其值。
registerOnChange(fn:(_:any)=>void):void{ this._onChange=fn; }
registerOnTouched(fn:any)与registerOnChange()此类似,它专门为控件接收触摸事件时注册一个处理程序。
registerOnTouched(fn:any):void{ this._onTouched=fn; }
setDisabledState?(isDisabled:boolean):void;是一个可选的方法,设置自定义表单的状态
setDisabledState(isDisabled:boolean):void{ this._renderer.setProperty(this._elementRef.nativeElement,'disabled',isDisabled); }
AbstractValueAccessor
我们可以把ControlValueAccessor中的方法写在一个抽象类中,不同的组件可以实现这个基类
exportabstractclassAbstractValueAccessorimplementsControlValueAccessor{ private_value:any=''; getvalue():any{ returnthis._value; } setvalue(v:any){ if(v!==this._value){ this._value=v; this.onChange(v); this.onTouched(); } } writeValue(value:any){ this._value=value; } onChange=(_)=>{}; onTouched=()=>{}; registerOnChange(fn:(_:any)=>void):void{ this.onChange=fn; } registerOnTouched(fn:()=>void):void{ this.onTouched=fn; } } exportfunctionMakeProvider(type:any):{provide:any,useExisting:any,multi:boolean}{ return{provide:NG_VALUE_ACCESSOR,useExisting:forwardRef(()=>type),multi:true}; }
Example
自定义一个list控件,可以选择年级
在线预览
git仓库
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。