【荐】深入Angular自定义表单控件
来源:互联网 发布:手机家装软件 编辑:程序博客网 时间:2024/06/14 00:07
推荐文章
Maxim Koretskyi :
Never again be confused when implementing ControlValueAccessor in Angular forms
推荐理由
在大型复杂的管理后台项目中,很有可能你会遇到需要自定义表单控件(Custom form control)。很多文章都介绍了此时应该定义ControlValueAccessor
,也展示了如何实现,但并没有说出为什么,这个类在Angular的表单架构中起了什么作用。该文章就解决了为什么的问题,让你从原理理解自定义表单控件。
文章概要
首先,只要你创建表单,Angular就会创建对应FormControl
,无论是模板驱动表单还是响应式表单。模板驱动表单的FormControl
是由NgModel
指令隐性创建,而响应式表单是由你自己创建,通过FormControlName
指令将Angular表单元素和原生表单元素进行绑定。
// packages/forms/src/directives/ng_model.ts@Directive({ selector: '[ngModel]...', ...})export class NgModel ... { _control = new FormControl(); <---------------- 这里
也就是说在Angular中的表单,不是原生表单,而是封装后的Angular表单。不仅仅是原生的表单控件可以处理封装成Angular表单,其他自定义的Angular组件也可以,只要定义了ControlValueAccessor
。
那ControlValueAccessor
是什么呢?它是原生元素和Angular表单之间的桥梁,将组件或者指令继承ControlValueAccessor
的接口就能变成Angular表单使用了。
ControlValueAccessor
接口长这样:
// packages/forms/src/directives/control_value_accessor.tsinterface ControlValueAccessor { writeValue(obj: any): void registerOnChange(fn: any): void registerOnTouched(fn: any): void ...}
writeValue
是在初始化的时候将formControl
的值传递给原生表单控件;registerOnChange
用来获取原生表单控件的值更新时通知Angular表单控件更新的函数;registerOnTouched
用来获取通知用户正在交互的函数。
明确来说,那些原生表单控件都有其对应的ControlValueAccessor
:
+------------------------------------+----------------------+| Accessor | Form Element |+------------------------------------+----------------------+| DefaultValueAccessor | input, textarea || CheckboxControlValueAccessor | input[type=checkbox] || NumberValueAccessor | input[type=number] || RadioControlValueAccessor | input[type=radio] || RangeValueAccessor | input[type=range] || SelectControlValueAccessor | select || SelectMultipleControlValueAccessor | select[multiple] |
那原生表单控件和Angular表单控件保持一致的原理是什么呢?
我们看下formControl
指令的实现:
// packages/forms/src/directives/reactive_directives/form_control_directive.tsexport class FormControlDirective ... { ... ngOnChanges(changes: SimpleChanges): void { if (this._isControlChanged(changes)) { setUpControl(this.form, this);
formControl
指令调用了setUpControl
函数来实现formControl
和ControlValueAccessor
之间的交互。
// packages/forms/src/directives/shared.tsexport function setUpControl(control: FormControl, dir: NgControl) { // 初始化原生表单控件 dir.valueAccessor.writeValue(control.value); // 监听原生表单控件,将值同步给form control dir.valueAccessor.registerOnChange((newValue: any) => { ... control.setValue(newValue, {emitModelToViewChange: false}); }); // 反之,监听form control,将值同步给原生表单控件 control.registerOnChange((newValue: any, ...) => { dir.valueAccessor.writeValue(newValue); });
到此,我们应该明白ControlValueAccessor
中定义writeValue
等函数是怎么work了吧。
以上就是最重要的原理部分。
接下来,作者通过第三方组件jquery-slider来演示了如何用Angular封装第三方组件库,以及如何将该组件封装成自定义表单控件。具体教程可以看原文。
延伸阅读
- semlinker: Angular 4.x 自定义表单控件
本文首发知乎野草。如有不当之处,欢迎指正。
- 【荐】深入Angular自定义表单控件
- angular表单认证大全&angular表单控件
- 自定义表单认证控件
- angular自定义表单验证----用户名唯一
- angular表单
- Angular自定义指令实现一般性的表单验证
- Angular如何在模板驱动表单中自定义校验器
- Android之自定义控件深入
- android自定义控件——深入篇
- angular表单验证
- 使用Angular提交表单
- angular 之表单验证
- angular js表单验证
- Angular 2 Form表单
- angular表单验证
- Angular 2 Form表单
- 使用Angular提交表单
- angular之表单验证
- Leetcode Remove Duplicates from Sorted Array 解题报告
- Lintcode 12. 带最小值操作的栈
- 实验10 GUI事件处理
- VMware Workstation Pro(虚拟机软件)官方专业版V14.1.0.7370693下载 | 含vmware workstation 14 密钥
- 数据结构实验之排序四:寻找大富翁
- 【荐】深入Angular自定义表单控件
- AbstractQueuedSynchronizer框架浅析
- 深度学习入门:Tensorflow实战Digit Recognizer
- 共同学习Java源代码-多线程与并发-ThreadPoolExecutor类(三)
- Java代码实现给图片添加文字水印 详细教程一
- webpack+gulp实现自动构建部署
- SQL CREATE DATABASE
- 字符游戏-智能蛇(学习体会)
- 微信小程序:点击图片进行预览