<mat-error> 从父组件中的自定义 formControl 继承验证时,在 ControlValueAccessor 中不工作
<mat-error> not working inside ControlValueAccessor when inheriting validations from custom formControl in parent component
<mat-error>
在子 ControlValueAccessor 组件中对父 formControl
验证没有影响。
<!-- Parent component template -->
<app-unique-name-text-box [formControl]="categoryName"></app-unique-name-text-box>
// Parent Component ts
this.addCategoryForm = fb.group({
'categoryName': ['', Validators.compose([Validators.required, BlankSpaceValidator.validate])]
});
this.categoryName = this.addCategoryForm.controls['categoryName'];
<!-- Child component template -->
<mat-form-field class="example-full-width">
<input matInput placeholder="Name" [formControl]="uniqueNameControl" (blur)="onInputBlur()">
<mat-error *ngIf="errorState">Enter a unique name</mat-error>
</mat-form-field>
// Child component ts
import {Component, OnInit, Optional, Self} from '@angular/core';
import {ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, NgControl} from '@angular/forms';
import {distinctUntilChanged} from "rxjs/operators";
@Component({
selector: 'app-unique-name-text-box',
templateUrl: './unique-name-text-box.component.html',
styleUrls: ['./unique-name-text-box.component.scss']
})
export class UniqueNameTextBoxComponent implements OnInit, ControlValueAccessor {
uniqueNameControl: FormControl = new FormControl('');
onChanged: any = () => {};
onTouched: any = () => {};
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) {
this.ngControl.valueAccessor = this;
}
this.uniqueNameControl.valueChanges.pipe(distinctUntilChanged()).subscribe(
val => this.setInputValue(val)
);
}
get errorState() {
return this.ngControl.errors !== null && !!this.ngControl.touched;
}
ngOnInit() {
}
registerOnChange(fn: any): void {
this.onChanged = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
writeValue(obj: any = ''): void {
this.uniqueNameControl.patchValue(obj);
}
setInputValue(val = '') {
this.uniqueNameControl.patchValue(val);
this.onChanged(val);
}
}
我是否需要在此处添加一些额外的配置以使 <mat-error>
在父级 formControl
上显示无效
您必须像这样手动将父控件验证器添加到子组件
试试这个:
ngOnInit() {
const validators = this.ngControl.control.validator;
this.uniqueNameControl.setValidators(validators ? validators : null);
this.uniqueNameControl.updateValueAndValidity();
}
ngAfterContentInit() {
// Subscribe to changes in the child control state in order to update the form field UI.
this.stateChanges.subscribe(() => {
return (this.errorState = !this.ngControl.control.valid);
}); }
<mat-error>
在子 ControlValueAccessor 组件中对父 formControl
验证没有影响。
<!-- Parent component template -->
<app-unique-name-text-box [formControl]="categoryName"></app-unique-name-text-box>
// Parent Component ts
this.addCategoryForm = fb.group({
'categoryName': ['', Validators.compose([Validators.required, BlankSpaceValidator.validate])]
});
this.categoryName = this.addCategoryForm.controls['categoryName'];
<!-- Child component template -->
<mat-form-field class="example-full-width">
<input matInput placeholder="Name" [formControl]="uniqueNameControl" (blur)="onInputBlur()">
<mat-error *ngIf="errorState">Enter a unique name</mat-error>
</mat-form-field>
// Child component ts
import {Component, OnInit, Optional, Self} from '@angular/core';
import {ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, NgControl} from '@angular/forms';
import {distinctUntilChanged} from "rxjs/operators";
@Component({
selector: 'app-unique-name-text-box',
templateUrl: './unique-name-text-box.component.html',
styleUrls: ['./unique-name-text-box.component.scss']
})
export class UniqueNameTextBoxComponent implements OnInit, ControlValueAccessor {
uniqueNameControl: FormControl = new FormControl('');
onChanged: any = () => {};
onTouched: any = () => {};
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) {
this.ngControl.valueAccessor = this;
}
this.uniqueNameControl.valueChanges.pipe(distinctUntilChanged()).subscribe(
val => this.setInputValue(val)
);
}
get errorState() {
return this.ngControl.errors !== null && !!this.ngControl.touched;
}
ngOnInit() {
}
registerOnChange(fn: any): void {
this.onChanged = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
writeValue(obj: any = ''): void {
this.uniqueNameControl.patchValue(obj);
}
setInputValue(val = '') {
this.uniqueNameControl.patchValue(val);
this.onChanged(val);
}
}
我是否需要在此处添加一些额外的配置以使 <mat-error>
在父级 formControl
上显示无效
您必须像这样手动将父控件验证器添加到子组件
试试这个:
ngOnInit() {
const validators = this.ngControl.control.validator;
this.uniqueNameControl.setValidators(validators ? validators : null);
this.uniqueNameControl.updateValueAndValidity();
}
ngAfterContentInit() {
// Subscribe to changes in the child control state in order to update the form field UI.
this.stateChanges.subscribe(() => {
return (this.errorState = !this.ngControl.control.valid);
}); }