ホームページ >ウェブフロントエンド >jsチュートリアル >Angular による ControlValueAccessor を使用してカスタム フォーム コントロールを実装する方法の詳細な説明
この記事では、AngularControlValueAccessor を使用してカスタム フォーム コントロールを実装する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
<form [formGroup]="simpleForm"> <br/> <other-component [form]="simpleForm"></other-component> <br/></form><br/>では、これらのカスタム コンポーネントをネイティブ フォームのように使用できるでしょうか?現在、オープン ソース コンポーネントの ng-zorro-antd フォーム コンポーネントでは、ネイティブ フォームと同じように formControlName 属性を使用できます。このタイプのコンポーネントはカスタム フォーム コンポーネントと呼ばれます。 [関連する推奨事項: "
angular チュートリアル "]
ControlValueAccessor
ControlValueAccessor インターフェイスは 4 つのメソッドを定義します。writeValue(obj: any): void<br/><br/>registerOnChange(fn: any): void<br/><br/>registerOnTouched(fn: any): void<br/><br/>setDisabledState(isDisabled: boolean)?: void<br/>
writeValue(obj: any) : フォーム モデルの新しい値をビューまたは DOM プロパティ (必要な場合) に書き込むメソッド。これにより、外部から内部データ モデルにデータが書き込まれます。データ フローの方向: フォーム モデル -> コンポーネント。
registerOnChange(fn: any): ビュー内の何かが変更されたときに呼び出されるハンドラーを登録する方法。他のフォーム ディレクティブやフォーム コントロールに値を更新するように指示する機能があります。通常、イベントトリガ関数は registerOnChange に保存する必要がありますが、データが変更された場合、イベントトリガ関数を呼び出すことで外部データに変更を通知し、変更されたデータをパラメータとして渡すことができます。データ フローの方向: コンポーネント -> フォーム モデル。
registerOnTouched(fn: any): onTouched イベントを登録します。基本的に registerOnChange と同じですが、この関数は、フォーム コンポーネントがタッチ状態にあることを通知し、フォーム コンポーネントを変更するために使用される点が異なります。バインドされた FormControl の内部状態。ステータス変更: コンポーネント -> フォーム モデル。
setDisabledState(isDisabled: boolean): FormControl 状態変更 API が呼び出され、フォーム状態が Disabled に変更されると、setDisabledState() メソッドが呼び出され、カスタム フォーム コンポーネントに通知されます。現在のフォームの読み取りステータス、書き込みステータス。ステータス変更: フォームモデル -> コンポーネント。
コントロール フレームワークを構築する
@Component({<br/> selector: 'app-test-control-value-accessor',<br/> templateUrl: './test-control-value-accessor.component.html',<br/> providers: [{<br/> provide: NG_VALUE_ACCESSOR,<br/> useExisting: forwardRef(() => TestControlValueAccessorComponent),<br/> multi: true<br/> }]<br/>})<br/>export class TestControlValueAccessorComponent implements ControlValueAccessor {<br/><br/> _counterValue = 0;<br/> <br/> private onChange = (_: any) => {};<br/><br/> constructor() { }<br/><br/> get counterValue() {<br/> return this._counterValue;<br/> }<br/><br/> set counterValue(value) {<br/> this._counterValue = value;<br/> // 触发 onChange,component 内部的值同步到 form model<br/> this.onChange(this._counterValue);<br/> }<br/><br/> increment() {<br/> this.counterValue++;<br/> }<br/><br/> decrement() {<br/> this.counterValue--;<br/> }<br/><br/> // form model 的值同步到 component 内部<br/> writeValue(obj: any): void {<br/> if (obj !== undefined) {<br/> this.counterValue = obj;<br/> }<br/> }<br/><br/> registerOnChange(fn: any): void {<br/> this.onChange = fn;<br/> }<br/><br/> registerOnTouched(fn: any): void { }<br/><br/> setDisabledState?(isDisabled: boolean): void { }<br/><br/>}<br/>
ControlValueAccessor を登録する
フォーム コントロールのControlValueAccessor を取得するために、Angular は
NG_VALUE_ACCESSOR トークンに登録されているすべての値を内部的に挿入します。コントロール自体を
DI フレームは、フォームがその値にアクセスできるようにするコントロールになります。したがって、必要なのは、
NG_VALUE_ACCESSOR 独自の値アクセサー インスタンス (コンポーネント) を使用してマルチプロバイダーを拡張することだけです。したがって、
multi: true を設定すると、この
token に対応するクラスが多数存在し、あちこちに散在していることを宣言することになります。
useExisting を使用する必要があります。これは、
TestControlValueAccessorComponent が、それを使用するコンポーネントのディレクティブ依存関係として作成される可能性があるためです。これには、
forwardRef の使用が必要です。この関数を使用すると、未定義のオブジェクトを参照できます。
@Component({<br/> ...<br/> providers: [<br/> { <br/> provide: NG_VALUE_ACCESSOR,<br/> useExisting: forwardRef(() => TestControlValueAccessorComponent ),<br/> multi: true<br/> }<br/> ]<br/>})<br/>export class TestControlValueAccessorComponent implements ControlValueAccessor {<br/> ...<br/>}<br/>
コントロール インターフェイス
<div class="panel panel-primary"><br/> <div class="panel-heading">自定义控件</div><br/> <div class="panel-body"><br/> <button (click)="increment()">+</button><br/> {{counterValue}}<br/> <button (click)="decrement()">-</button><br/> </div><br/></div><br/>
フォーム
<div class="constainer"><br/> <form #form="ngForm"><br/> <app-test-control-value-accessor name="message" [(ngModel)]="message"></app-test-control-value-accessor><br/> <button type="button" (click)="submit(form.value)">Submit</button><br/> </form><br/> <pre class="brush:php;toolbar:false">{{ message }}
@Component({<br/> selector: 'app-root',<br/> templateUrl: './app.component.html',<br/> styleUrls: ['./app.component.css']<br/>})<br/>export class AppComponent {<br/><br/> message = 5;<br/><br/> submit(value: any): void {<br/> console.log(value);<br/> }<br/><br/>}<br/>
プログラミング関連の知識について詳しくは、プログラミング ビデオをご覧ください。 !
以上がAngular による ControlValueAccessor を使用してカスタム フォーム コントロールを実装する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。