如何控制自定义表单控件内的子组件验证

问题描述 投票:0回答:1

我有一个自定义表单控件,里面有许多输入框,以及一些其他组件。当我的自定义验证器验证失败时,我发现所有输入框都读取表单验证失败并设置它们自己变成红色,但事实是它们没有问题,我如何禁用它们自动读取验证状态,并手动控制

enter image description here

这是我制作的一个简化示例,您可以看到错误已传播到两个控件。如何精确控制错误显示? 示例

angular angular-forms ng-zorro-antd
1个回答
0
投票

问题是错误与

formControl
“myData”有关。

当你有一个

  <nz-form-item>
    <nz-form-label [nzSpan]="7" nzRequired>my custom component</nz-form-label>
    <nz-form-control [nzSpan]="12" nzHasFeedback>
      <app-quality-rule formControlName="myData"></app-quality-rule>
    </nz-form-control>
  </nz-form-item>

ng-zorro 将“ant-input-group-wrapper-status-error”类添加到所有内部“inputs-group”

您可以与班级一起飞行,也可以不使用自定义表单控件并在组件中使用

viewProviders:[{ provide: ControlContainer, useExisting: FormGroupDirective}]

使用viewProviders,一切都改变了。看到现在 validateForm 被称为

this.validateForm = this.fb.group({
  email: ['', [Validators.email, Validators.required]],
  myData: this.fb.group({
    value1: ['', [this.validate('value1')]],
    value2: ['', [this.validate('value2')]],
  }),
});

我们添加自定义函数验证为

  validate(controlName: string) {
    return (control: AbstractControl) => {
      const myData = control.value as MyData;
      const error: any = {};
      if (controlName == 'value1' && !control.value)
        return { [MyDataError.value1Error]: 'value1 error' };

      if (controlName == 'value2' && !control.value)
        return { [MyDataError.value2Error]: 'value2 error' };

      return null;
    };
  }

quality-rile.component 变得更加简单 .ts

@Component({
  selector: 'app-quality-rule',
  templateUrl: './quality-rule.component.html',
  viewProviders:[{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class QualityRuleComponent implements AfterViewInit {
  protected readonly MyDataError = MyDataError;
  
  fromControl!:FormGroup
  constructor(public form:FormGroupDirective){
  }
  ngAfterViewInit(){
    setTimeout(()=>{
      this.fromControl=this.form.form.get('myData') as FormGroup
    })
  }
}

但是 .html 发生了变化,看看我们如何添加 formGroup 和所有元素,就像我们不拆分表单一样

<ng-container *ngIf="fromControl" [formGroup]="fromControl">
  <nz-form-item>
    <nz-form-control nzHasFeedback>
      <nz-input-group nzAddOnBefore="input1">
        <input formControlName="value1" nz-input />
      </nz-input-group>
    </nz-form-control>
  </nz-form-item>
  <nz-alert
    style="margin-top: 10px;margin-bottom: 5px"
    *ngIf="form.form?.hasError(MyDataError.value1Error, 'myData.value1')"
    nzType="error"
    [nzDescription]="MyDataError.value1Error"
  ></nz-alert>
  <nz-form-item>
  <nz-form-control nzHasFeedback>
    <nz-input-group nzAddOnBefore="input1">
      <input formControlName="value2" nz-input />
    </nz-input-group>
  </nz-form-control>
</nz-form-item>
  <nz-alert
    style="margin-top: 10px;margin-bottom: 5px"
    *ngIf="form.form?.hasError(MyDataError.value2Error, 'myData.value2')"
    nzType="error"
    [nzDescription]="MyDataError.value2Error"
  ></nz-alert>
</ng-container>

最后,app.cpmponent.html 变成这样

<form nz-form [formGroup]="validateForm">
  <nz-form-item>
    <nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label>
    <nz-form-control [nzSpan]="12" nzHasFeedback>
      <input
        nz-input
        formControlName="email"
        placeholder="email"
        type="email"
      />
    </nz-form-control>
  </nz-form-item>

  <div nz-row>
    <nz-form-label [nzSpan]="7" nzRequired>my custom component</nz-form-label>
    <div nz-col [nzSpan]="12" nzHasFeedback>
      <app-quality-rule></app-quality-rule>
    </div>
  </div>
</form>

查看stackblitz

注意:也许,再过一段时间,我会尝试使用自定义表单控件,但我不太确定何时:(

© www.soinside.com 2019 - 2024. All rights reserved.