Angular使用ControlValueAccessor創(chuàng)建自定義表單控件
在 Angular 自定義表單控件,有時(shí)你想要的輸入不是標(biāo)準(zhǔn)的文本輸入、選擇或復(fù)選框。通過(guò)實(shí)現(xiàn)ControlValueAccessor 接口并將組件注冊(cè)為 NG_VALUE_ACCESSOR,您可以將自定義表單控件無(wú)縫地集成到模板驅(qū)動(dòng)或響應(yīng)表單中,就像它是本地表單一樣!
ControlValueAccessor
ControlValueAccessor 是一個(gè)接口,充當(dāng)Angular API 和 DOM 元素之間的橋梁
ControlValueAccessor 是一個(gè)連接表單模型和視圖(DOM元素)的接口,自定義的表單控件必須實(shí)現(xiàn)這個(gè)接口,它的作用是:
- 把 form 模型中值映射到視圖中
- 當(dāng)視圖發(fā)生變化時(shí),通知 form directives 或 form controls
Angular 引入這個(gè)接口的原因是,不同的輸入控件數(shù)據(jù)更新方式是不一樣的。例如,對(duì)于我們常用的文本輸入框來(lái)說(shuō),我們是設(shè)置它的 value 值,而對(duì)于復(fù)選框 (checkbox) 我們是設(shè)置它的 checked 屬性。實(shí)際上,不同類型的輸入控件都有一個(gè) ControlValueAccessor,用來(lái)更新視圖
Angular 中常見(jiàn)的 ControlValueAccessor 有:
- DefaultValueAccessor - 用于 text 和 textarea 類型的輸入控件
- SelectControlValueAccessor - 用于 select 選擇控件
- CheckboxControlValueAccessor - 用于 checkbox 復(fù)選控件
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)是一個(gè)方法,用于注冊(cè)在視圖中的某些內(nèi)容發(fā)生更改時(shí)應(yīng)調(diào)用的處理程序。它獲取一個(gè)函數(shù),告訴其他表單指令和表單控件更新其值。
registerOnChange(fn: (_: any) => void): void {
this._onChange = fn;
}
registerOnTouched(fn:any)與registerOnChange()此類似,它專門為控件接收觸摸事件時(shí)注冊(cè)一個(gè)處理程序。
registerOnTouched(fn: any): void {
this._onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void; 是一個(gè)可選的方法,設(shè)置自定義表單的狀態(tài)
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
AbstractValueAccessor
我們可以把 ControlValueAccessor 中的方法寫在一個(gè)抽象類中,不同的組件可以實(shí)現(xiàn)這個(gè)基類
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
自定義一個(gè) list 控件,可以選擇年級(jí)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Angular2實(shí)現(xiàn)組件交互的方法分析
這篇文章主要介紹了Angular2實(shí)現(xiàn)組件交互的方法,結(jié)合實(shí)例形式總結(jié)分析了Angular2中組件交互的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-12-12
Angular outlet實(shí)現(xiàn)頁(yè)面布局示例詳解
這篇文章主要為大家介紹了Angular outlet實(shí)現(xiàn)頁(yè)面布局示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
基于angular2 的 http服務(wù)封裝的實(shí)例代碼
這篇文章主要介紹了基于angular2 的 http服務(wù)封裝實(shí)例代碼,2017-06-06
Angularjs渲染的 using 指令的星級(jí)評(píng)分系統(tǒng)示例
本篇文章主要介紹了Angularjs渲染的 using 指令的星級(jí)評(píng)分系統(tǒng)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
angular多選表單數(shù)據(jù)綁定的簡(jiǎn)單嘗試
AngularJS中數(shù)據(jù)綁定相信大家應(yīng)該都不陌生了,這篇文章主要給大家介紹了關(guān)于angular多選表單數(shù)據(jù)綁定的簡(jiǎn)單嘗試,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Ubuntu系統(tǒng)下Angularjs開(kāi)發(fā)環(huán)境安裝
本文主要介紹 Ubuntu系統(tǒng)下Angularjs開(kāi)發(fā)環(huán)境安裝,這里詳細(xì)介紹了安裝步驟和注意事項(xiàng),有在Ubuntu 環(huán)境下開(kāi)發(fā)的朋友可以參考下2016-09-09
BootStrap+Angularjs+NgDialog實(shí)現(xiàn)模式對(duì)話框
在完成一個(gè)后臺(tái)管理系統(tǒng)時(shí),需要用表格顯示注冊(cè)用戶的信息。但是用戶地址太長(zhǎng)了,不好顯示。所以想做一個(gè)模式對(duì)話框,點(diǎn)擊詳細(xì)地址按鈕時(shí),彈出對(duì)話框,顯示地址。下面小編給大家分享下實(shí)現(xiàn)方法,一起看下吧2016-08-08
詳解Angularjs 自定義指令中的數(shù)據(jù)綁定
這篇文章主要介紹了Angularjs 自定義指令中的數(shù)據(jù)綁定,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07

