この記事は主に Angular19 カスタム フォーム コントロールに関する関連情報を紹介します。非常に優れており、必要な友人は参考にしてください。
1 要件
開発者が特定のフォーム コントロールを必要とする場合。デフォルトで提供されるフォーム コントロールと同様のコントロールをフォーム コントロールとして開発するには、カスタマイズされたフォーム コントロールは、モデルとビューの間でデータがどのように相互作用するかを考慮する必要があります2 公式ドキュメント -> クリックして移動
Angular は、開発者がカスタム フォーム コントロールを構築するのを支援する ControlValueAccessor インターフェイスを提供します。開発者は、interface ControlValueAccessor { writeValue(obj: any): void registerOnChange(fn: any): void registerOnTouched(fn: any): void setDisabledState(isDisabled: boolean)?: void }
間のデータ対話を実装するために、カスタム フォーム コントロール クラスの ControlValueAccessor インターフェイスにメソッドを実装するだけで済みます。 2.1 writeValue
writeValue(obj: any): voidこのメソッドは、カスタム フォーム コントロールの要素に値を書き込むために使用されます。このパラメーター値 (obj) は、テンプレートを通じてこのカスタム フォーム コントロールを使用するコンポーネントです。フォームまたはレスポンシブのデータ バインディングフォームが渡されます。カスタム フォーム コントロールのクラスでは、この値 (obj) をメンバー変数に割り当てるだけで、カスタム フォーム コントロールのビューが属性を通じてバインドされます。
2.2 registerOnChange
registerOnChange(fn: any): voidカスタム フォーム コントロールのデータが変更されると、registerOnChange メソッドがトリガーされ、registerOnChange によって受け取られたカスタム フォーム コントロールのデータの変更を処理します。メソッド ( fn ) は実際にはメソッドであり、変更されたデータの処理を担当しますカスタム コントロール データが変更されると、 fn によって実行されるメソッドが自動的に呼び出されますが、通常のアプローチはメソッド propagateChange をカスタマイズしてカスタム メソッドを実行させることですこのように、データが変更されたときに、propagateChange を呼び出すだけで、変更されたデータを処理できます
2.3 registerOnTouched
registerOnTouched(fn: any): voidフォーム コントロールがタッチされると、registerOnTouched メソッドがトリガーされます。更新予定...2018-1- 31 11:18:33
2.4 setDisabledState
setDisabledState(isDisabled: boolean)?: void更新予定...2018-1-31 11:19:30
3 プログラミング手順
3.1 カスタムフォームコントロールコンポーネントの作成
<p> <h4 id="当前计数为-countNumber">当前计数为:{{countNumber}}</h4> <br /> <p> <button md-icon-button (click)="onIncrease()"> <span>增加</span> <md-icon>add</md-icon> </button> <span style="margin-left: 30px;"></span> <button md-icon-button (click)="onDecrease()"> <span>减少</span> <md-icon>remove</md-icon> </button> </p> </p>HTML
import { Component, OnInit } from '@angular/core'; import { ControlValueAccessor } from '@angular/forms'; @Component({ selector: 'app-counter', templateUrl: './counter.component.html', styleUrls: ['./counter.component.scss'] }) export class CounterComponent implements OnInit { countNumber: number = 0; constructor() { } ngOnInit() { } onIncrease() { this.countNumber++; } onDecrease() { this.countNumber--; } }3
.1.1 機能説明
増加ボタンをクリックすると現在のカウントが1増加し、現在のカウントが1減ります減少ボタンをクリックしたとき3.1.2 他で直接コンポーネントで使用するとエラーが報告されます
3.2
3.2.1 ControlValueAccessor インターフェイスを実装する
export class CounterComponent implements OnInit, ControlValueAccessor { countNumber: number = 0; constructor() { } ngOnInit() { } onIncrease() { this.countNumber++; } onDecrease() { this.countNumber--; } /**将数据从模型传输到视图 */ writeValue(obj: any): void { } /**将数据从视图传播到模型 */ registerOnChange(fn: any): void { } registerOnTouched(fn: any): void { } setDisabledState?(isDisabled: boolean): void { } }
3.2.2 依存関係情報プロバイダーの指定
import { Component, OnInit, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-counter', templateUrl: './counter.component.html', styleUrls: ['./counter.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CounterComponent), multi: true } ] }) export class CounterComponent implements OnInit, ControlValueAccessor { countNumber: number = 0; constructor() { } ngOnInit() { } onIncrease() { this.countNumber++; } onDecrease() { this.countNumber--; } /**将数据从模型传输到视图 */ writeValue(obj: any): void { } /**将数据从视图传播到模型 */ registerOnChange(fn: any): void { } registerOnTouched(fn: any): void { } setDisabledState?(isDisabled: boolean): void { } }
3. 2.3 修正すべきバグ
フォームコントロール内の要素は、フォームから渡されたデータを受け入れることができません; フォーム コントロールを使用してコンポーネント内のモデルを作成し、フォーム コントロールによって変更されたデータをフォーム コントロールを使用してコンポーネント内のフォーム モデルに戻すことはできません。つまり、モデルとビューの間にデータのやり取りはありません。3.3 モデルとビュー間のデータ対話を練習する
3.3.1 モデルからビューへ
カスタムフォームコントロールクラスのwriteValueメソッドでリファクタリングする
ヒント01: writeValueメソッドのパラメータは、カスタム フォーム コントロールを使用したコンポーネントのデータ バインディング3.3.2 モデルへのビュー
》メソッドをカスタマイズするカスタム フォーム コントロールで変化するデータを処理するには
propagateChange = (_: any) => {};》カスタム フォーム コントロールの registerOnChange メソッドをリファクタリングしますフォームコントロールクラス
/**将数据从视图传播到模型 */ registerOnChange(fn: any): void { this.propagateChange = fn; }》データが変化するカスタムメソッドを呼び出す
3.4 カスタムフォームコントロールコンポーネントのコードまとめ
<p> <h4 id="当前计数为-countNumber">当前计数为:{{countNumber}}</h4> <br /> <p> <button md-icon-button (click)="onIncrease()"> <span>增加</span> <md-icon>add</md-icon> </button> <span style="margin-left: 30px;"></span> <button md-icon-button (click)="onDecrease()"> <span>减少</span> <md-icon>remove</md-icon> </button> </p> </p>HTML
import { Component, OnInit, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-counter', templateUrl: './counter.component.html', styleUrls: ['./counter.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CounterComponent), multi: true } ] }) export class CounterComponent implements OnInit, ControlValueAccessor { countNumber: number = 0; propagateChange = (_: any) => {}; constructor() { } ngOnInit() { } onIncrease() { this.countNumber++; this.propagateChange(this.countNumber); } onDecrease() { this.countNumber--; this.propagateChange(this.countNumber); } /**将数据从模型传输到视图 */ writeValue(obj: any): void { this.countNumber = obj; } /**将数据从视图传播到模型 */ registerOnChange(fn: any): void { /**fn其实是一个函数,当视图中的数据改变时就会调用fn指向的这个函数,从而达到将数据传播到模型的目的 */ this.propagateChange = fn; // 将fn的指向赋值给this.propagateChange,在需要将改变的数据传到模型时只需要调用this.propagateChange方法即可 } registerOnTouched(fn: any): void { } setDisabledState?(isDisabled: boolean): void { } }3.5 カスタムフォームコントロールを使用するコンポーネントのコードまとめ
技巧01:如果自定义表单控件和使用自定义表单控件的组件都在不在同一个模块时需要对自定义表单控件对应组件进行导出和导入操作
<p class="panel panel-primary"> <p class="panel-heading">面板模板</p> <p class="panel-body"> <h3 id="面板测试内容">面板测试内容</h3> </p> <p class="panel-footer">2018-1-22 10:22:20</p> </p> <p class="panel-primary"> <p class="panel-heading">自定义提取表单控件</p> <p class="panel-body"> <form #myForm=ngForm> <app-counter name="counter" [(ngModel)]="countNumber"> </app-counter> </form> <h6 id="绿线上是自定义提取的表单控件显示的内容">绿线上是自定义提取的表单控件显示的内容</h6> <hr style="border: solid green 2px" /> <h6 id="绿线下是使用自定义表单控件时表单的实时数据">绿线下是使用自定义表单控件时表单的实时数据</h6> <h3 id="表单控件的值为-myForm-value-nbsp-nbsp-json">表单控件的值为:{{myForm.value | json}}</h3> </p> <p class="panel-footer">2018-1-31 10:09:17</p> </p> <p class="panel-primary"> <p class="panel-heading">提取表单控件</p> <p class="panel-body"> <form #form="ngForm"> <p>outerCounterValue value: {{outerCounterValue}}</p> <app-exe-counter name="counter" [(ngModel)]="outerCounterValue"></app-exe-counter> <br /> <button md-raised-button type="submit">Submit</button> <br /> <p> {{form.value | json}} </p> </form> </p> <p class="panel-footer">2018-1-27 21:51:45</p> </p> <p class="panel panel-primary"> <p class="panel-heading">ngIf指令测试</p> <p class="panel-body"> <button md-rasied-button (click)="onChangeNgifValue()">改变ngif变量</button> <br /> <p *ngIf="ngif; else ngifTrue" > <h4 id="ngif变量的值为true">ngif变量的值为true</h4> </p> <ng-template #ngifTrue> <h4 id="ngif变量的值为false">ngif变量的值为false</h4> </ng-template> </p> <p class="panel-footer">2018-1-27 16:58:17</p> </p> <p class="panel panel-primary"> <p class="panel-heading">RXJS使用</p> <p class="panel-body"> <h4 id="测试内容">测试内容</h4> </p> <p class="panel-footer">2018-1-23 21:14:49</p> </p> <p class="panel panel-primary"> <p class="panel-heading">自定义验证器</p> <p class="panel-body"> <form (ngSubmit)="onTestLogin()" [formGroup]="loginForm"> <md-input-container> <input mdInput placeholder="请输入登录名" formControlName="username" /> </md-input-container> <br /> <md-input-container> <input mdInput placeholder="请输入密码" formControlName="userpwd" /> </md-input-container> <br /> <button type="submit" md-raised-button>登陆</button> </form> </p> <p class="panel-footer">2018-1-23 11:06:01</p> </p> <p class="panel panel-primary"> <p class="panel-heading">响应式表单</p> <p class="panel-body"> <form [formGroup]="testForm"> <md-input-container> <input mdInput type="text" placeholder="请输入邮箱" formControlName="email" /> <span mdSuffix>@163.com</span> </md-input-container> <br /> <md-input-container> <input mdInput type="password" placeholder="请输入密码" formControlName="password" /> </md-input-container> </form> <hr /> <p> <h2 id="表单整体信息如下">表单整体信息如下:</h2> <h4 id="表单数据有效性-testForm-valid">表单数据有效性:{{testForm.valid}}</h4> <h4 id="表单数据为-testForm-value-nbsp-nbsp-json">表单数据为:{{testForm.value | json}}</h4> <h4 id="获取单个或多个FormControl-testForm-controls-email-nbsp">获取单个或多个FormControl:{{testForm.controls['email'] }}</h4> <hr /> <h2 id="email输入框的信息如下">email输入框的信息如下:</h2> <h4 id="有效性-testForm-get-email-valid">有效性:{{testForm.get('email').valid}}</h4> <h4 id="email输入框的错误信息为-testForm-get-email-errors-nbsp-nbsp-json">email输入框的错误信息为:{{testForm.get('email').errors | json}}</h4> <h4 id="required验证结果-testForm-hasError-required-nbsp-email-nbsp-nbsp-json">required验证结果:{{testForm.hasError('required', 'email') | json}}</h4> <h4 id="minLength验证结果-nbsp-testForm-hasError-minLength-nbsp-email-nbsp-nbsp-json-nbsp">minLength验证结果:{{ testForm.hasError('minLength', 'email') | json }}</h4> <h4 id="hello-nbsp-testForm-controls-email-errors-nbsp-nbsp-json-nbsp">hello:{{ testForm.controls['email'].errors | json }}</h4> <hr /> <h2 id="password输入框啊的信息如下">password输入框啊的信息如下:</h2> <h4 id="有效性-testForm-get-password-valid">有效性:{{testForm.get('password').valid}}</h4> <h4 id="password输入框的错误信息为-testForm-get-password-errors-nbsp-nbsp-json-nbsp">password输入框的错误信息为:{{testForm.get('password').errors | json }}</h4> <h4 id="required验证结果-testForm-hasError-required-nbsp-password-nbsp-nbsp-json">required验证结果:{{testForm.hasError('required', 'password') | json}}</h4> </p> <p> <button nd-rasied-button (click)="onTestClick()">获取数据</button> <h4 id="data变量-data">data变量:{{data}}</h4> </p> </p> <p class="panel-footer">2018-1-22 15:58:43</p> </p> <p class="panel panel-primary"> <p class="panel-heading">利用响应式编程实现表单元素双向绑定</p> <p class="panel-body"> <md-input-container> <input mdInput placeholder="请输入姓名(响应式双向绑定):" [formControl]="name"/> </md-input-container> <p> 姓名为:{{name.value}} </p> </p> <p class="panel-footer">2018-1-22 11:12:35</p> </p> --> <p class="panel panel-primary"> <p class="panel-heading">模板表单</p> <p class="panel-body"> <md-input-container> <input mdInput placeholder="随便输入点内容" #a="ngModel" [(ngModel)]="desc" name="desc" /> <button type="button" md-icon-button mdSuffix (click)="onTestNgModelClick()"> <md-icon>done</md-icon> </button> </md-input-container> <p> <h3 id="名为desc的表单控件的值为-nbsp-a-value-nbsp">名为desc的表单控件的值为:{{ a.value }}</h3> </p> </p> <p class="panel-footer">2018-1-22 10:19:31</p> </p> <p class="panel panel-primary"> <p class="panel-heading">md-chekbox的使用</p> <p calss="panel-body"> <p> <md-checkbox #testCheckbox color="primary" checked="true">测试</md-checkbox> </p> <p *ngIf="testCheckbox.checked"> <h2 id="测试checkbox被选中啦">测试checkbox被选中啦</h2> </p> </p> <p class="panel-footer">2018-1-18 14:02:20</p> </p> <p class="panel panel-primary"> <p class="panel-heading">md-tooltip的使用</p> <p class="panel-body"> <span md-tooltip="重庆火锅">鼠标放上去</span> </p> <p class="panel-footer">2018-1-18 14:26:58</p> </p> <p class="panel panel-primary"> <p class="panel-heading">md-select的使用</p> <p class="panel-body"> <md-select placeholder="请选择目标列表" class="fill-width" style="height: 40px;"> <md-option *ngFor="let taskList of taskLists" [value]="taskList.name">{{taskList.name}}</md-option> </md-select> </p> <p class="panel-footer">2018-1-18 14:26:58</p> </p> <p class="panel panel-primary"> <p class="panel-heading">ngNonBindable指令的使用</p> <p class="panel-body"> <h3 id="描述">描述</h3> <p>使用了ngNonBindable的标签,会将该标签里面的元素内容全部都看做时纯文本</p> <h3 id="例子">例子</h3> <p> <span>{{taskLists | json }}</span> <span ngNonBindable>← 这是{{taskLists | json }}渲染的内容</span> </p> </p> <p class="panel-footer">2018-1-19 09:34:26</p> </p>
HTML
import { Component, OnInit, HostListener, Inject} from '@angular/core'; import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms'; import { Http } from '@angular/http'; import { QuoteService } from '../../service/quote.service'; @Component({ selector: 'app-test01', templateUrl: './test01.component.html', styleUrls: ['./test01.component.scss'] }) export class Test01Component implements OnInit { countNumber: number = 9; outerCounterValue: number = 5; ngif = true; loginForm: FormGroup; testForm: FormGroup; data: any; name: FormControl = new FormControl(); desc: string = 'hello boy'; taskLists = [ {label: 1, name: '进行中'}, {label: 2, name: '已完成'} ]; constructor( private formBuilder: FormBuilder, private http: Http, @Inject('BASE_CONFIG') private baseConfig, private quoteService: QuoteService ) {} ngOnInit() { this.testForm = new FormGroup({ email: new FormControl('', [Validators.required, Validators.minLength(4)], []), password: new FormControl('', [Validators.required], []) }); this.name.valueChanges .debounceTime(500) .subscribe(value => alert(value)); this.loginForm = this.formBuilder.group({ username: ['', [Validators.required, Validators.minLength(4), this.myValidator], []], userpwd: ['', [Validators.required, Validators.minLength(6)], []] }); this.quoteService.test() .subscribe(resp => console.log(resp)); } onChangeNgifValue() { if (this.ngif == false) { this.ngif = true; } else { this.ngif = false; } } @HostListener('keyup.enter') onTestNgModelClick() { alert('提交'); } onTestClick() { // this.data = this.testForm.get('email').value; // console.log(this.testForm.getError); console.log(this.testForm.controls['email']); } onTestLogin() { console.log(this.loginForm.value); if (this.loginForm.valid) { console.log('登陆数据合法'); } else { console.log('登陆数据不合法'); console.log(this.loginForm.controls['username'].errors); console.log(this.loginForm.get('userpwd').errors); } } myValidator(fc: FormControl): {[key: string]: any} { const valid = fc.value === 'admin'; return valid ? null : {myValidator: {requiredUsername: 'admin', actualUsername: fc.value}}; } }
3.6 初始化效果展示
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上がAngular19 でのカスタム フォーム コントロールの使用についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ホットトピック









