从父组件中的自定义formControl继承验证时,<mat-error>在ControlValueAccessor内部不起作用

时间:2020-01-11 10:14:54

标签: angular angular-material controlvalueaccessor

子ControlValueAccessor组件中的

<mat-error>对父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上显示无效

2 个答案:

答案 0 :(得分:2)

您必须像这样手动将父控件验证器添加到子组件

尝试一下:

 ngOnInit() {
    const validators = this.ngControl.control.validator;
    this.uniqueNameControl.setValidators(validators ? validators : null);
    this.uniqueNameControl.updateValueAndValidity();
 }

Example

答案 1 :(得分:0)

  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);
    });   }