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 相关文章推荐
动态加载iframe
Jun 16 Javascript
js之WEB开发调试利器:Firebug 下载
Jan 13 Javascript
jquery DOM操作 基于命令改变页面
May 06 Javascript
HTML5附件拖拽上传drop & google.gears实现代码
Apr 28 Javascript
js实现圆盘记速表
Aug 03 Javascript
easyui Draggable组件实现拖动效果
Aug 19 Javascript
详解JavaScript中数组和字符串的lastIndexOf()方法使用
Mar 13 Javascript
jQuery代码性能优化的10种方法
Jun 21 Javascript
jQuery Ajax使用FormData上传文件和其他数据后端web.py获取
Jun 11 jQuery
详解Puppeteer前端自动化测试实践
Feb 21 Javascript
Vue时间轴 vue-light-timeline的用法说明
Oct 29 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
Jan 20 Vue.js
小程序测试后台服务的方法(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无限分类源码分享(思路不错)
2011/10/13 PHP
PHP中的替代语法简介
2014/08/22 PHP
php 使用redis锁限制并发访问类示例
2016/11/02 PHP
JavaScript设置FieldSet展开与收缩
2009/05/15 Javascript
加载远程图片时,经常因为缓存而得不到更新的解决方法(分享)
2013/06/26 Javascript
javascript判断office版本示例
2014/04/11 Javascript
使用JQuery FancyBox插件实现图片展示特效
2015/11/16 Javascript
js性能优化技巧
2015/11/29 Javascript
微信小程序 wxapp内容组件 icon详细介绍
2016/10/31 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
Angular5中调用第三方库及jQuery的添加的方法
2018/06/07 jQuery
vue新vue-cli3环境配置和模拟json数据的实例
2018/09/19 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
2020/03/26 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
Vue打包部署到Nginx时,css样式不生效的解决方式
2020/08/03 Javascript
[48:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 VG vs KG
2018/03/31 DOTA
用tensorflow搭建CNN的方法
2018/03/05 Python
python 动态调用函数实例解析
2019/10/21 Python
python 五子棋如何获得鼠标点击坐标
2019/11/04 Python
OpenCV+Python--RGB转HSI的实现
2019/11/27 Python
python numpy 反转 reverse示例
2019/12/04 Python
Python通过VGG16模型实现图像风格转换操作详解
2020/01/16 Python
Python使用itcaht库实现微信自动收发消息功能
2020/07/13 Python
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码
2020/04/10 HTML / CSS
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
美国沙龙美发产品购物网站:Hair.com by L’Oreal
2020/11/09 全球购物
金属材料工程毕业生个人的自我评价
2013/11/28 职场文书
企业业务员岗位职责
2014/03/14 职场文书
个人授权委托书范本
2014/04/03 职场文书
2015年度学校卫生工作总结
2015/05/12 职场文书
教师考核鉴定意见
2015/06/05 职场文书
工伤事故赔偿协议书
2015/08/06 职场文书
会议主持词通用版
2019/04/02 职场文书
html5调用摄像头实例代码
2021/06/28 HTML / CSS
golang 实用库gotable的具体使用
2021/07/01 Golang