Angular使用ControlValueAccessor創(chuàng)建自定義表單控件
在 Angular 自定義表單控件,有時(shí)你想要的輸入不是標(biāo)準(zhǔn)的文本輸入、選擇或復(fù)選框。通過實(shí)現(xiàn)ControlValueAccessor 接口并將組件注冊(cè)為 NG_VALUE_ACCESSOR,您可以將自定義表單控件無縫地集成到模板驅(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ì)于我們常用的文本輸入框來說,我們是設(shè)置它的 value 值,而對(duì)于復(fù)選框 (checkbox) 我們是設(shè)置它的 checked 屬性。實(shí)際上,不同類型的輸入控件都有一個(gè) ControlValueAccessor,用來更新視圖
Angular 中常見的 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)文章
高效利用Angular中內(nèi)置服務(wù)$http、$location等
這篇文章主要介紹了如何高效利用Angular中內(nèi)置服務(wù),大家知道的Angular內(nèi)置服務(wù)有哪些,感興趣的小伙伴們可以參考一下2016-03-03深入理解Angularjs向指令傳遞數(shù)據(jù)雙向綁定機(jī)制
這篇文章主要深入的給大家介紹了Angularjs向指令傳遞數(shù)據(jù),雙向綁定機(jī)制的相關(guān)資料,需要的朋友可以參考下2016-12-12AngularJS實(shí)現(xiàn)的鼠標(biāo)拖動(dòng)畫矩形框示例【可兼容IE8】
這篇文章主要介紹了AngularJS實(shí)現(xiàn)的鼠標(biāo)拖動(dòng)畫矩形框,涉及基于AngularJS的事件響應(yīng)及頁面元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-05-05詳解在Angular項(xiàng)目中添加插件ng-bootstrap
這篇文章主要介紹了詳解在 Angular 項(xiàng)目中添加插件 ng-bootstrap,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07AngularJS路由實(shí)現(xiàn)頁面跳轉(zhuǎn)實(shí)例
這篇文章主要為大家詳細(xì)介紹了AngularJS路由實(shí)現(xiàn)頁面跳轉(zhuǎn)的實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03全面解析Angular中$Apply()及$Digest()的區(qū)別
$apply()和$digest()在AngularJS中是兩個(gè)核心概念,但是有時(shí)候它們又讓人困惑。這篇文章主要介紹了Angular中$Apply()及$Digest()區(qū)別詳細(xì)說明的相關(guān)資料,需要的朋友可以參考下2016-08-08