這篇文章主要介紹了Angular如何使用ControlValueAccessor實現(xiàn)自定義表單控件,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)于2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元德惠做網(wǎng)站,已為上家服務(wù),為德惠各地企業(yè)和個人服務(wù),聯(lián)系電話:028-86922220
本篇文章給大家介紹一下Angular使用ControlValueAccessor實現(xiàn)自定義表單控件的方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助。
我們在實際開發(fā)中,通常會遇到各種各樣的定制化功能,會遇到有些組件會與 Angular 的表單進行交互,這時候我們一般會從外部傳入一個 FormGroup 對象,然后在組件的內(nèi)部寫相應(yīng)的邏輯對 Angular 表單進行操作。如果我們只是對表單中的一個項進行定制,將整個表單對象傳入顯然不合適,并且組件也會顯得臃腫。
<form [formGroup]="simpleForm"> <other-component [form]="simpleForm"></other-component> </form>
那么,我們能不能像原生表單一樣去使用這些自定義組件呢?目前,開源組件 ng-zorro-antd 表單組件能和原生表單一樣使用 formControlName 這個屬性,這類組件就叫自定義表單組件。
在 Angular 中,使用 ControlValueAccessor 可以實現(xiàn)組件與外層包裹的 form 關(guān)聯(lián)起來。
ControlValueAccessor是用于處理以下內(nèi)容的接口:
將表單模型中的值寫入視圖/ DOM
在視圖/ DOM更改時通知其他表單指令和控件
ControlValueAccessor
ControlValueAccessor 接口定義了四個方法:
writeValue(obj: any): void registerOnChange(fn: any): void registerOnTouched(fn: any): void setDisabledState(isDisabled: boolean)?: void
writeValue(obj:any)
:將表單模型中的新值寫入視圖或DOM屬性(如果需要)的方法,它將來自外部的數(shù)據(jù)寫入到內(nèi)部的數(shù)據(jù)模型。數(shù)據(jù)流向: form model -> component。
registerOnChange(fn:any)
:一種注冊處理程序的方法,當視圖中的某些內(nèi)容發(fā)生更改時應(yīng)調(diào)用該處理程序。它具有一個告訴其他表單指令和表單控件以更新其值的函數(shù)。通常在 registerOnChange 中需要保存該事件觸發(fā)函數(shù),在數(shù)據(jù)改變的時候,可以通過調(diào)用事件觸發(fā)函數(shù)通知外部數(shù)據(jù)變了,同時可以將修改后的數(shù)據(jù)作為參數(shù)傳遞出去。數(shù)據(jù)流向: component -> form model。
registerOnTouched(fn: any)
:注冊 onTouched 事件,基本同 registerOnChange ,只是該函數(shù)用于通知表單組件已經(jīng)處于 touched 狀態(tài),改變綁定的 FormControl 的內(nèi)部狀態(tài)。狀態(tài)變更: component -> form model。
setDisabledState(isDisabled: boolean)
:當調(diào)用 FormControl 變更狀態(tài)的 API 時得表單狀態(tài)變?yōu)?Disabled 時調(diào)用 setDisabledState() 方法,以通知自定義表單組件當前表單的讀寫狀態(tài)。狀態(tài)變更: form model -> component。
搭建控件框架
@Component({ selector: 'app-test-control-value-accessor', templateUrl: './test-control-value-accessor.component.html', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TestControlValueAccessorComponent), multi: true }] }) export class TestControlValueAccessorComponent implements ControlValueAccessor { _counterValue = 0; private onChange = (_: any) => {}; constructor() { } get counterValue() { return this._counterValue; } set counterValue(value) { this._counterValue = value; // 觸發(fā) onChange,component 內(nèi)部的值同步到 form model this.onChange(this._counterValue); } increment() { this.counterValue++; } decrement() { this.counterValue--; } // form model 的值同步到 component 內(nèi)部 writeValue(obj: any): void { if (obj !== undefined) { this.counterValue = obj; } } registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { } setDisabledState?(isDisabled: boolean): void { } }
注冊 ControlValueAccessor
為了獲得 ControlValueAccessor
用于表單控件,Angular 內(nèi)部將注入在 NG_VALUE_ACCESSOR
令牌上注冊的所有值,這是將控件本身注冊到 DI
框架成為一個可以讓表單訪問其值的控件。因此,我們需要做的就是NG_VALUE_ACCESSOR
使用我們自己的值訪問器實例(這是我們的組件)擴展 multi-provider 。所以設(shè)置 multi: true
,是聲明這個 token
對應(yīng)的類很多,分散在各處。
這里我們必須使用 useExisting
,因為TestControlValueAccessorComponent
可能在使用它的組件中被其創(chuàng)建為指令依賴項。這就得用到 forwardRef
了,這個函數(shù)允許我們引用一個尚未定義的對象。
@Component({ ... providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TestControlValueAccessorComponent ), multi: true } ] }) export class TestControlValueAccessorComponent implements ControlValueAccessor { ... }
控件界面
test-control-value-accessor.component.html
<div class="panel panel-primary"> <div class="panel-heading">自定義控件</div> <div class="panel-body"> <button (click)="increment()">+</button> {{counterValue}} <button (click)="decrement()">-</button> </div> </div>
在表單中使用
app.component.html
<div class="constainer"> <form #form="ngForm"> <app-test-control-value-accessor name="message" [(ngModel)]="message"></app-test-control-value-accessor> <button type="button" (click)="submit(form.value)">Submit</button> </form> <pre>{{ message }}</pre> </div>
app.component.ts
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { message = 5; submit(value: any): void { console.log(value); } }
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Angular如何使用ControlValueAccessor實現(xiàn)自定義表單控件”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
當前文章:Angular如何使用ControlValueAccessor實現(xiàn)自定義表單控件
鏈接URL:http://muchs.cn/article38/gedcpp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、搜索引擎優(yōu)化、網(wǎng)站收錄、營銷型網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)