gpt4 book ai didi

Angular Material - 带有错误状态的自定义响应式(Reactive)表单控件

转载 作者:太空狗 更新时间:2023-10-29 17:03:32 25 4
gpt4 key购买 nike

我正在关注 this tutorial来自 Angular Material 网站关于创建自定义表单控件。本教程中没有关于在出现验证错误时如何处理表单控件错误的示例。

custom-text.component.html

<mat-form-field class="example-full-width">
<mat-select [placeholder]="placeholder" #select [formControl]="control">
<mat-option *ngFor="let food of foods" [value]="food">
{{food}}
</mat-option>
</mat-select>
<mat-error>This is required.</mat-error>
</mat-form-field>

custom-text.component.ts

import { Component, ViewChild, HostBinding, Input, ChangeDetectionStrategy, Optional, Self, DoCheck, OnInit, NgZone } from '@angular/core';
import { ControlValueAccessor, NgControl, NgForm, FormGroupDirective, FormControlDirective, FormControlName, FormControl, FormBuilder } from '@angular/forms';
import { MatFormFieldControl, MatSelect, CanUpdateErrorState, ErrorStateMatcher } from '@angular/material';

@Component({
selector: 'custom-text',
templateUrl: './custom-text.component.html',
styleUrls: [
'./custom-text.component.scss'
],
providers: [
{
provide: MatFormFieldControl,
useExisting: CustomTextComponent
}
],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CustomTextComponent implements ControlValueAccessor, OnInit, DoCheck {

@Input()
foods: string[];

@Input()
get errorStateMatcher(): ErrorStateMatcher {
return this.select.errorStateMatcher;
}
set errorStateMatcher(val) {
this.select.errorStateMatcher = val;
}

@Input()
get placeholder() {
return this.select.placeholder;
}
set placeholder(plh) {
this.select.placeholder = plh;
this.stateChanges.next();
}

@Input()
get value() {
return this.select.value;
}
set value(val) {
this.select.value = val;
this.stateChanges.next();
}

@ViewChild('select')
select: MatSelect;

control: FormControl;

constructor(
@Optional() @Self() ngControl: NgControl,
@Optional() private _controlName: FormControlName) {
if (ngControl) {
ngControl.valueAccessor = this;
}
}

ngOnInit(): void {
this.control = this._controlName.control;
}

ngDoCheck(): void {
this.select.updateErrorState();
}

writeValue(obj: any): void {
this.value = obj;
}
registerOnChange(fn: any): void {
this.select.registerOnChange(fn);
}
registerOnTouched(fn: any): void {
this.select.registerOnTouched(fn);
}
setDisabledState?(isDisabled: boolean): void {
this.select.setDisabledState(isDisabled);
}


}

app.component.html

<div style="text-align:center">
<form class="example-form" [formGroup]="myForm" (submit)="submitForm()">
<custom-text [foods]="[null, 'burger', 'spaghetti', 'fries']"
formControlName="selectedFood"
[errorStateMatcher]="matcher"></custom-text>
<button>Submit</button>
</form>
</div>

基本上,我将 FormControlName 实例注入(inject)到自定义控件中。

constructor(
@Optional() private _controlName: FormControlName) {
....
ngOnInit(): void {
this.control = this._controlName.control;
}

然后我将它的 control 属性绑定(bind)到内部 mat-select 控件中。

<mat-select [placeholder]="placeholder" #select [formControl]="control">

然后我在 ngDoCheck 中调用 this.select.updateErrorState

这是 StackBlitz 的链接: https://stackblitz.com/edit/angular-c4ufpp

是否有更好或更标准的方法?

最佳答案

不要使用创建循环错误依赖项的 Validator 接口(interface),而是在您的自定义组件中添加 errorState 来检查注入(inject)到构造函数中的 ngControl,就像这样:

get errorState() {
return this.ngControl.errors !== null && !!this.ngControl.touched;
}

这使得 DoCheck 变得不必要了。在您的父组件中,不要使用 errorMatcher,而是使用普通的 Angular 验证器,如下所示:

selectedFood = new FormControl('burger', [Validators.required]);

关于Angular Material - 带有错误状态的自定义响应式(Reactive)表单控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52017000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com