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 相关文章推荐
js 完美图片新闻轮转效果,腾讯大粤网首页图片轮转改造而来
Nov 21 Javascript
JavaScript在多浏览器下for循环的使用方法
Nov 07 Javascript
JS简单实现文件上传实例代码(无需插件)
Nov 15 Javascript
jquery+json实现数据列表分页示例代码
Nov 15 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
Sep 10 Javascript
编写自己的jQuery提示框(Tip)插件
Feb 05 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
May 26 Javascript
微信小程序之批量上传并压缩图片的实例代码
Jul 05 Javascript
vuex如何重置所有state(可定制)
Jan 17 Javascript
VUE渲染后端返回含有script标签的html字符串示例
Oct 28 Javascript
环形加载进度条封装(Vue插件版和原生js版)
Dec 04 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
May 25 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
DOTA2 1月28日更新:监管系统降临刀塔世界
2021/01/28 DOTA
如何隐藏你的.php文件
2007/01/04 PHP
深入解析PHP中的(伪)多线程与多进程
2013/07/01 PHP
php中用memcached实现页面防刷新功能
2014/08/19 PHP
thinkphp模板继承实例简述
2014/11/26 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
简单的pgsql pdo php操作类实现代码
2016/08/25 PHP
CI框架附属类用法分析
2018/12/26 PHP
得到文本框选中的文字,动态插入文字的js代码
2007/03/07 Javascript
JavaScript定义类和对象的方法
2014/11/26 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
ubuntu下安装nodejs以及升级的办法
2015/05/08 NodeJs
js获取腾讯视频ID的方法
2016/10/03 Javascript
vue router路由嵌套不显示问题的解决方法
2017/06/17 Javascript
three.js实现3D模型展示的示例代码
2017/12/31 Javascript
微信小程序自定义底部弹出框
2020/11/16 Javascript
Vue 监听列表item渲染事件方法
2018/09/06 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
2019/05/15 Javascript
NProgress显示顶部进度条效果及使用详解
2019/09/21 Javascript
jQuery实现移动端笔触canvas电子签名
2020/05/21 jQuery
浅析Git版本控制器使用
2017/12/10 Python
对Python字符串中的换行符和制表符介绍
2018/05/03 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
pytorch训练imagenet分类的方法
2018/07/27 Python
Python可迭代对象操作示例
2019/05/07 Python
Python 读取串口数据,动态绘图的示例
2019/07/02 Python
Django对数据库进行添加与更新的例子
2019/07/12 Python
学习和使用python的13个理由
2019/07/30 Python
tensorflow 变长序列存储实例
2020/01/20 Python
Python之变量类型和if判断方式
2020/05/05 Python
scrapy头部修改的方法详解
2020/12/06 Python
软件测试题目
2013/02/27 面试题
舞蹈兴趣小组活动总结
2014/07/07 职场文书
员工生日活动方案
2014/08/24 职场文书
关于安全的广播稿
2014/10/23 职场文书
汽车销售员岗位职责
2015/04/11 职场文书