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 相关文章推荐
javascript flash下fromCharCode和charCodeAt方法使用说明
Jan 12 Javascript
javascript椭圆旋转相册实现代码
Jan 16 Javascript
网页整体变灰白色(兼容各浏览器)实例
Apr 21 Javascript
jQuery之排序组件的深入解析
Jun 19 Javascript
快速掌握Node.js模块封装及使用
Mar 21 Javascript
JavaScript实现简单的日历效果
Sep 25 Javascript
详解基于javascript实现的苹果系统底部菜单
Dec 02 Javascript
浅谈Express异步进化史
Sep 09 Javascript
vue+element创建动态的form表单及动态生成表格的行和列
May 20 Javascript
微信小程序实现批量倒计时功能
Nov 01 Javascript
google广告之另类js调用实现代码
Aug 22 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
Dec 09 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编程中数组的指针的使用
2015/11/30 PHP
CodeIgniter多语言实现方法详解
2016/01/20 PHP
Yii CFileCache 获取不到值的原因分析
2017/02/08 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
js实现单行文本向上滚动效果实例代码
2013/11/28 Javascript
JavaScript保留两位小数的2个自定义函数
2014/05/05 Javascript
使用不同的方法结合/合并两个JS数组
2014/09/18 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
Javascript中Array.prototype.map()详解
2014/10/22 Javascript
javascript实现在下拉列表中显示多级树形菜单的方法
2015/08/12 Javascript
bootstrap datetimepicker日期插件使用方法
2017/01/13 Javascript
JavaScript正则替换HTML标签功能示例
2017/03/02 Javascript
jQuery插件HighCharts实现气泡图效果示例【附demo源码】
2017/03/13 Javascript
VUE 更好的 ajax 上传处理 axios.js实现代码
2017/05/10 Javascript
ES6 javascript中class静态方法、属性与实例属性用法示例
2017/10/30 Javascript
bootstrap fileinput插件实现预览上传照片功能
2018/01/23 Javascript
Vue自定义过滤器格式化数字三位加一逗号实现代码
2018/03/23 Javascript
JS中使用react-tooltip插件实现鼠标悬浮显示框
2019/05/15 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
2020/11/16 Javascript
[00:55]2015国际邀请赛中国区预选赛5月23日——28日约战上海
2015/05/25 DOTA
python 文件查找及内容匹配方法
2018/10/25 Python
python生成九宫格图片
2018/11/19 Python
python tkinter实现界面切换的示例代码
2019/06/14 Python
用Anaconda安装本地python包的方法及路径问题(图文)
2019/07/16 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
2019/10/04 Python
安踏官方商城:anta.cn
2019/12/16 全球购物
会计出纳岗位职责
2013/12/25 职场文书
清明节扫墓活动方案
2014/03/02 职场文书
六个一活动实施方案
2014/03/21 职场文书
图书馆志愿者活动总结
2014/06/27 职场文书
大学四年个人总结
2015/03/03 职场文书
求职自我推荐信
2015/03/24 职场文书
python爬虫之利用selenium模块自动登录CSDN
2021/04/22 Python
Python 图片添加美颜效果
2022/04/28 Python
JAVA springCloud项目搭建流程
2022/05/11 Java/Android