玩转Angular2(5)--自定义input表单控件
更新日期:
因为项目原因又玩上了Angular2(v4.0+),《玩转Angular2》系列用于探索一些灵活或者新的用法。
本文简单介绍封装使用ngModol实现自定义表单控件的过程。
NgModel相关
NgModel
NgModel
用于从作用域创建一个FormControl
实例,并将它绑定到一个表单控制元素。
[ngModel]
: 单向绑定,作用域变更将同步到UI木板[(ngModel)]
: 双向绑定,UI模版的变更也将同步到作用域
NgModel
继承自NgControl
。
NgControl
NgControl
是所有控制指令继承的基础类。它将一个FormControl
绑定到DOM元素。
FormControl
、FormGroup
和FormArray
,三者都用于angular表单的值和状态的跟踪,区别在于是一个控件、一组控件或者是它们的组合。
AbstractControl
是三个具体表单类的抽象基类。并为它们提供了一些共同的行为和属性,其中有些是可观察对象(Observable
)。FormControl
用于跟踪一个单独的表单控件的值和有效性状态。它对应于一个HTML表单控件,比如输入框和下拉框。FormGroup
用于跟踪一组AbstractControl
的实例的值和有效性状态。该组的属性中包含了它的子控件。组件中的顶级表单就是一个FormGroup
。FormArray
用于跟踪AbstractControl
实例组成的有序数组的值和有效性状态。
ControlValueAccessor
ControlValueAccessor
用于在控制和原生元素之间建立联系,它封装了赋值到一个表现为input
元素的DOM元素。
简单说,就是angular中的input是带有[(ngModel)]
这个属性的,而我们想要自己控制这个input的写入过程,使用ControlValueAccessor
就可以做到。
ControlValueAccessor
提供以下接口:
writeValue(obj: any) : void
: 写入值到元素registerOnChange(fn: any) : void
: 设置当控件接收到change
事件时触发的回调registerOnTouched(fn: any) : void
: 设置当控件接收到touch
事件时触发的回调setDisabledState(isDisabled: boolean) : void
: 该函数将在控件状态或者disabled
值变化,根据值来对元素启用或失效
ControlValueAccessor
继承自DefaultValueAccessor
。
DefaultValueAccessor
DefaultValueAccessor
提供值写入和监听变化的默认访问,像NgModel
, FormControlDirective
, 和FormControlName
指令会使用。
DefaultValueAccessor
提供类包括:
onChange : (_: any) => {}
:change
事件变化监听onTouched : () => {}
:touch
事件变化监听
以及ControlValueAccessor
(上面)的接口。
NG_VALUE_ACCESSOR
NG_VALUE_ACCESSOR
提供一个ControlValueAccessor
供表单控制使用。
时间选择控件
datetimepicker
这里我们主要使用一个Bootstrap和jQuery的日期时间选择器插件–bootstrap-datetimepick。
先简单介绍一下,我们可以使用该插件方便地进行日期和时间选择,从最大的十年视图到最小的分钟选择都可以自行调整。
具体一些配置项大家可以到官网上查看,这里就不详细介绍了,后面代码用到的会简单进行说明。
首先我们需要下载代码,这里放在了assets/plugins/datepicker
文件夹里面。
然后添加进我们的应用程序就可以使用了:
|
|
创建自定义input控件
我们想要封装后的组件跟原生的angular组件一样,像表现为input的自定义控件,我们想要使用[(ngModel)]
来进行双向绑定,我们需要使用ControlValueAccessor
来拓展。
而这里ControlValueAccessor
只是一个接口,我们应用它,还需要获取一些可用的服务,这时候需要注入NG_VALUE_ACCESSOR
。
|
|
这里简单讲讲几个概念:
- 我们自定义了一个访问控制服务,该服务包装为
NG_VALUE_ACCESSOR
服务,主要用于控制ControlValueAccessor
相关的访问。 - 我们需要将自定义input控件提供给
NG_VALUE_ACCESSOR
,以便通过自定义方式控制父组件的[(ngModel)]
以及其他表单相关的访问。 forwardRef
用于将目前还未获取到的依赖关联起来,这里我们关联后面的自定义Input组件。
|
|
具体的实现实例参考Angular2 + Connect custom component to ngModel。
创建自定义时间选择控件
像我们定义一个时间选择控件,一般需要对外提供一些配置:
- 选择精度(或自定义视图范围)
- 这里提供:分钟(默认)、小时和天
- 可选日期范围
- 是否禁用
- 是否必填
- …
以及通常我们提供一个值变更的回调,像(change)
这样的事件。
下面看看代码实现:
|
|
抽象出class继承
我们可以把相同的方法抽象出来,通过继承的方式,这样就能在多个相似组件通用了。
|
|
在datetimepick中继承:
|
|
效果图:
结束语
这节我们讲了自定义表单相关的一些概念,以及自定义一个时间选择input表单的实现过程。
很多时候我们都需要对不同的input自行封装,所以也可以单独抽象出来Class方便继承,又或者封装成指令等方式都是可以的。
此处查看项目代码
此处查看页面效果
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢
码生艰难,写文不易,给我家猪囤点猫粮了喵~