Dieser Artikel stellt hauptsächlich die relevanten Informationen zu den benutzerdefinierten Formularsteuerelementen von Angular19 vor. Er ist sehr gut und hat Referenzwert.
1 Anforderungen
Wenn Entwickler ein bestimmtes Formularsteuerelement benötigen, müssen sie ein Steuerelement entwickeln, das dem standardmäßig bereitgestellten Formularsteuerelement ähnelt, da ein benutzerdefiniertes Formularsteuerelement die Beziehung zwischen dem Modell und der Ansicht berücksichtigen muss mit Daten interagieren
2 Offizielles Dokument-> Klicken Sie hier, um zu gehen
Angular Die ControlValueAccessor-Schnittstelle wird Entwicklern zur Verfügung gestellt, um Entwickler beim Erstellen benutzerdefinierter Formularsteuerelemente zu unterstützen. Entwickler müssen lediglich die Methoden in der ControlValueAccessor-Schnittstelle in der benutzerdefinierten Formularsteuerelementklasse implementieren, um eine Dateninteraktion zwischen dem Modell und der Ansicht zu erreichen
interface ControlValueAccessor { writeValue(obj: any): void registerOnChange(fn: any): void registerOnTouched(fn: any): void setDisabledState(isDisabled: boolean)?: void }
2.1 writeValue
writeValue(obj: any): void
Diese Methode wird verwendet, um Werte in Elemente in benutzerdefinierten Formularsteuerelementen zu schreiben;
Dieser Parameterwert (obj) verwendet die Komponenten von Benutzerdefinierte Formularsteuerelemente werden über die Datenbindung des Vorlagenformulars oder des Responsive-Formulars übergeben.
In der Klasse des benutzerdefinierten Formularsteuerelements müssen Sie diesen Wert (obj) nur einer Mitgliedsvariablen, der Ansicht, zuweisen des benutzerdefinierten Formularsteuerelements zeigt diesen Wert durch Attributbindung an
2.2 registerOnChange
registerOnChange(fn: any): void
registerOnChange wird ausgelöst, wenn sich die Daten der benutzerdefinierten Formularsteuerelementmethode ändern wird verwendet, um Änderungen in benutzerdefinierten Formularsteuerdaten zu verarbeiten. Der von der
registerOnChange-Methode empfangene Parameter (fn) ist tatsächlich eine Methode, die für die Verarbeitung der geänderten Daten verantwortlich ist.
Wenn das Steuerelement definiert ist Wenn sich Daten ändern, wird die von fn ausgeführte Methode automatisch aufgerufen. Der übliche Ansatz besteht jedoch darin, eine Methode propagateChange anzupassen und die benutzerdefinierte Methode auf fn zeigen zu lassen, sodass Sie bei Datenänderungen nur propagateChange aufrufen müssen, um die geänderten Daten zu verarbeiten
2.3 registerOnTouched
registerOnTouched(fn: any): void
Die Methode registerOnTouched wird ausgelöst, wenn das Formularsteuerelement berührt wird...2018-1-31 11: 18:33
2.4 setDisabledState
setDisabledState(isDisabled: boolean)?: void
Wird aktualisiert...2018-1-31 11:19:30
3 Programmierschritte
3.1 Erstellen Sie eine benutzerdefinierte Formularsteuerkomponente
<p> <h4>当前计数为:{{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 Funktionsbeschreibung
Wenn Sie auf die Schaltfläche „Erhöhen“ klicken, wird die aktuelle Zählung um 1 erhöht. Wenn Sie auf die Schaltfläche „Verringern“ klicken, wird die aktuelle Zählung um 1 verringert
3.1.2 Bei direkter Verwendung in anderen Komponenten wird ein Fehler gemeldet
Die Fehlermeldung lautet wie folgt :
Die Fehlermeldung lautet: Angenommen, die von uns verwendete Komponente
3.2 So erstellen Sie das
3.2.1 Implementieren Sie die ControlValueAccessor-Schnittstelle
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 Abhängigkeitsinformationsanbieter angeben
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 Zu behebender Fehler
Obwohl es kann normal ausgeführt werden, die Elemente im Formularsteuerelement können das in der Komponente mithilfe des Formularsteuerelements übergebene Formularmodell nicht akzeptieren. Die Daten und die durch das Formularsteuerelement geänderten Daten können nicht an das Formularmodell in der Komponente zurückgegeben werden, die das Formularsteuerelement verwendet Kurz gesagt, es gibt keine Dateninteraktion zwischen dem Modell und der Ansicht
3.3 Üben Sie die Dateninteraktion zwischen Modell und Ansicht
3.3.1 Modell zur Ansicht
Refaktorisieren Sie die writeValue-Methode in der benutzerdefinierten Formularsteuerelementklasse
Tipp 01: Die Parameter in der writeValue-Methode werden über die Datenbindung des Formulars mithilfe der Komponente übergeben, die die benutzerdefinierte verwendet Formularsteuerung
3.3.2 Ansicht Gehe zum Modell
》Passen Sie eine Methode an, um die geänderten Daten im benutzerdefinierten Formular zu verarbeiten control
propagateChange = (_: any) => {};
》Refactoring der Methode „registerOnChange“ in der benutzerdefinierten Formularsteuerklasse
/**将数据从视图传播到模型 */ registerOnChange(fn: any): void { this.propagateChange = fn; }
》Rufen Sie die benutzerdefinierte Methode auf, bei der sich die Daten ändern
3.4 Codezusammenfassung der benutzerdefinierten Formularsteuerkomponente
<p> <h4>当前计数为:{{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 Codezusammenfassung der Komponente, die benutzerdefinierte Formularsteuerelemente verwendet
技巧01:如果自定义表单控件和使用自定义表单控件的组件都在不在同一个模块时需要对自定义表单控件对应组件进行导出和导入操作
<p class="panel panel-primary"> <p class="panel-heading">面板模板</p> <p class="panel-body"> <h3>面板测试内容</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>绿线上是自定义提取的表单控件显示的内容</h6> <hr style="border: solid green 2px" /> <h6>绿线下是使用自定义表单控件时表单的实时数据</h6> <h3>表单控件的值为:{{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 style="background-color: red; color: white" >ngif变量的值为true</h4> </p> <ng-template #ngifTrue> <h4 style="background-color: black; color: white">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>测试内容</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>表单整体信息如下:</h2> <h4>表单数据有效性:{{testForm.valid}}</h4> <h4>表单数据为:{{testForm.value | json}}</h4> <h4>获取单个或多个FormControl:{{testForm.controls['email'] }}</h4> <hr /> <h2>email输入框的信息如下:</h2> <h4>有效性:{{testForm.get('email').valid}}</h4> <h4>email输入框的错误信息为:{{testForm.get('email').errors | json}}</h4> <h4>required验证结果:{{testForm.hasError('required', 'email') | json}}</h4> <h4>minLength验证结果:{{ testForm.hasError('minLength', 'email') | json }}</h4> <h4>hello:{{ testForm.controls['email'].errors | json }}</h4> <hr /> <h2>password输入框啊的信息如下:</h2> <h4>有效性:{{testForm.get('password').valid}}</h4> <h4>password输入框的错误信息为:{{testForm.get('password').errors | json }}</h4> <h4>required验证结果:{{testForm.hasError('required', 'password') | json}}</h4> </p> <p> <button nd-rasied-button (click)="onTestClick()">获取数据</button> <h4>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>名为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>测试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>描述</h3> <p>使用了ngNonBindable的标签,会将该标签里面的元素内容全部都看做时纯文本</p> <h3>例子</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 初始化效果展示
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
JavaScript中Object基础内部方法图(图文教程)
Das obige ist der detaillierte Inhalt vonInformationen zur Verwendung benutzerdefinierter Formularsteuerelemente in Angular19. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!