Angular使用ControlValueAccessor创建自定义表单控件


Posted in Javascript onMarch 08, 2019

在 Angular 自定义表单控件,有时你想要的输入不是标准的文本输入、选择或复选框。通过实现ControlValueAccessor 接口并将组件注册为 NG_VALUE_ACCESSOR,您可以将自定义表单控件无缝地集成到模板驱动或响应表单中,就像它是本地表单一样!

ControlValueAccessor

ControlValueAccessor 是一个接口,充当Angular API 和 DOM 元素之间的桥梁

ControlValueAccessor 是一个连接表单模型和视图(DOM元素)的接口,自定义的表单控件必须实现这个接口,它的作用是:

  • 把 form 模型中值映射到视图中
  • 当视图发生变化时,通知 form directives 或 form controls

Angular 引入这个接口的原因是,不同的输入控件数据更新方式是不一样的。例如,对于我们常用的文本输入框来说,我们是设置它的 value 值,而对于复选框 (checkbox) 我们是设置它的 checked 属性。实际上,不同类型的输入控件都有一个 ControlValueAccessor,用来更新视图

Angular 中常见的 ControlValueAccessor 有:

  • DefaultValueAccessor - 用于 text 和 textarea 类型的输入控件
  • SelectControlValueAccessor - 用于 select 选择控件
  • CheckboxControlValueAccessor - 用于 checkbox 复选控件
export interface ControlValueAccessor {
 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 中的方法写在一个抽象类中,不同的组件可以实现这个基类

export abstract class AbstractValueAccessor implements ControlValueAccessor {
 
 private _value: any = '';
 
 get value(): any {
 return this._value;
 }

 set value(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;
 }
}

export function MakeProvider(type: any): { provide: any, useExisting: any, multi: boolean} {
 return { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => type), multi: true };
}

Example

自定义一个 list 控件,可以选择年级

在线预览
git仓库

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
dojo随手记 gird组件引用
Feb 24 Javascript
jQuery 对Select的操作备忘记录
Jul 04 Javascript
jQuery简易图片放大特效示例代码
Jun 09 Javascript
浅谈javascript的调试
Jan 28 Javascript
jquery带下拉菜单和焦点图代码分享
Aug 24 Javascript
微信开发 JS-SDK 6.0.2 经常遇到问题总结
Dec 08 Javascript
jQuery菜单实例(全选,反选,取消)
Aug 28 jQuery
jQuery EasyUI开发技巧总结
Sep 26 jQuery
解决修复npm安装全局模块权限的问题
May 17 Javascript
原生JS实现动态添加新元素、删除元素方法
May 05 Javascript
jquery实现垂直手风琴菜单
Mar 04 jQuery
uni-app 微信小程序授权登录的实现步骤
Feb 18 Javascript
小程序测试后台服务的方法(ngrok)
Mar 08 #Javascript
详解JavaScript函数callee、call、apply的区别
Mar 08 #Javascript
利用angular自动编译andriod APK的绕坑经历分享
Mar 08 #Javascript
详解小程序循环require之坑
Mar 08 #Javascript
详解js 创建对象的几种方法
Mar 08 #Javascript
浅谈Javascript常用正则表达式应用
Mar 08 #Javascript
validform表单验证的实现方法
Mar 08 #Javascript
You might like
php 获得汉字拼音首字母的函数
2009/08/01 PHP
javascript动画浅析
2012/08/30 Javascript
Javascript将双字节字符转换成单字节字符并计算长度
2016/06/22 Javascript
JS跨域交互(jQuery+php)之jsonp使用心得
2016/07/01 Javascript
浅谈Nodejs应用主文件index.js
2016/08/28 NodeJs
JavaScript面试题(指针、帽子和女朋友)
2016/11/23 Javascript
JavaScript中数组Array方法详解
2017/02/27 Javascript
Vue制作Todo List网页
2017/04/26 Javascript
详解使用nvm安装node.js
2017/07/18 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
Javascript var变量删除原理及实现
2020/08/26 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
Django1.7+python 2.78+pycharm配置mysql数据库
2016/10/09 Python
Python分治法定义与应用实例详解
2017/07/28 Python
在Pycharm中将pyinstaller加入External Tools的方法
2019/01/16 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
python的re模块使用方法详解
2019/07/26 Python
Django 通过JS实现ajax过程详解
2019/07/30 Python
Python socket模块方法实现详解
2019/11/05 Python
HTML5网页录音和上传到服务器支持PC、Android,支持IOS微信功能
2019/04/26 HTML / CSS
摩托车和ATV零件、配件和服装的首选在线零售商:MotoSport
2017/12/22 全球购物
法国面料和小百货在线商店:Mondial Tissus
2019/03/23 全球购物
Yummie官方网站:塑身衣和衣柜必需品
2019/10/29 全球购物
微软马来西亚官方网站:Microsoft马来西亚
2019/11/22 全球购物
二年级语文教学反思
2014/02/02 职场文书
《童年的发现》教学反思
2014/02/14 职场文书
高中生家长寄语大全
2014/04/03 职场文书
尊老爱亲美德少年事迹材料
2014/08/14 职场文书
合作协议书格式
2014/08/19 职场文书
孝老爱亲事迹材料
2014/12/24 职场文书
2015年导购员工作总结
2015/04/25 职场文书
学生会招新宣传语
2015/07/13 职场文书
竞聘书的秘诀
2019/04/02 职场文书
导游词之包公祠
2019/11/25 职场文书
mybatis 解决从列名到属性名的自动映射失败问题
2021/06/30 Java/Android
基于python定位棋子位置及识别棋子颜色
2021/07/26 Python