Angular FormControl 检查是否需要

Angular FormControl check if required

有没有办法检查是否需要控制?

当我实现一个接受 FormControl 并且不仅有 input 而且还有验证错误的专用表单字段组件时,问题就出现了。由于某些字段是必需的,因此最好让用户知道 * 是否需要它。

有没有办法检查 @Input() control: FormControl 是否为 Validators.required 并显示星号?

你可以这样做:

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators, AbstractControl } from '@angular/forms';

@Component({...})
export class AppComponent  {
  form: FormGroup = new FormGroup({
    control: new FormControl(null, Validators.required)
  });

  get validator() {
    const validator = this.form.get('control').validator({} as AbstractControl);
    console.log(validator);
    if (validator && validator.required) {
      return true;
    }
  }
}

然后在您的模板中:

<form [formGroup]="form" (submit)="onSubmit()">
  Control: <span *ngIf="validator">*</span> <input type="text" formControlName="control">
  <button>Submit</button>
</form>

注意: 使用此 this.form.get('control').validator({} as AbstractControl);

只需将表单控件作为 AbstractControl 的一种类型

这将 return 一个对象,其中包含您 FormControl 上存在的验证器列表。然后您可以检查对象中的 required 键。如果它存在并且它的值为 true 那么您可以确定在 FormControl.

上应用了 Required Validator

这里有一个 Working Sample StackBlitz 供您参考。

我需要一些更抽象的东西,所以我对@siddajmera 的答案进行了一些调整,以便能够在 any 字段上使用。

在您的 .ts 文件中:

isRequiredField(field: string) {
    const form_field = this.testForm.get(field);
    if (!form_field.validator) {
        return false;
    }

    const validator = form_field.validator({} as AbstractControl);
    return (validator && validator.required);
}

然后,在您的模板文件中:

<div>
    <label>Some Field:<span *ngIf="isRequiredField('some_field')">*</span></label>
    <input [formControl]="form.controls['some_field']">
</div>
<div>
    <label>Some Field:<span *ngIf="isRequiredField('another_field')">*</span></label>
    <input [formControl]="form.controls['another_field']">
</div>

您可以使用所需的属性。

<input type="text" formControlName="control" placeholder="Some Field" required>

此外,它有助于 CSS 样式设置或辅助功能目的。

我来晚了一点,但我认为这可以通过使用 Pipe 来解决。上面的答案解决了你的问题,但有一个小警告。通过在您的模板中直接使用 method/getter,此函数将在每次更改检测 运行 时执行,如 this article 中所述。在您的简短示例中,这可能不是性能问题,但在较大的表单中可能是个问题。

我的解决方案

通过使用纯管道,一旦管道的输入值发生变化,就会触发对提供的控件的检查。我已将 ControlRequiredPipe 添加到 AppModule providersdeclarations 部分。当管道添加到 providers 部分时,它也可以在 Component TypeScript class 中使用。我已将此行为包含在 AppComponent.

OnSubmit 函数中

Stackblitz example

AppComponent:

<form [formGroup]="form" (submit)="onSubmit()">
  Control: <strong *ngIf="form.get('control') | controlRequired">*</strong>
  <input type="text" formControlName="control">
  <button>Submit</button>
</form>
import { Component } from "@angular/core";
import { FormGroup, FormControl, Validators } from "@angular/forms";
import { ControlRequiredPipe } from "./control-required.pipe";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  form: FormGroup = new FormGroup({
    control: new FormControl(null, [
      Validators.required,
      Validators.minLength(8)
    ])
  });

  constructor(private controlRequiredPipe: ControlRequiredPipe) {}

  onSubmit() {
    alert(
      `The required state of the FormControl is: ${this.controlRequiredPipe.transform(
        this.form.get("control")
      )}`
    );
  }
}

ControlRequiredPipe:

import { Pipe, PipeTransform } from "@angular/core";
import { AbstractControl } from "@angular/forms";

@Pipe({
  name: "controlRequired"
})
export class ControlRequiredPipe implements PipeTransform {
  public transform(control: AbstractControl): boolean {
    //  Return when no control or a control without a validator is provided
    if (!control || !control.validator) {
      return false;
    }

    //  Return the required state of the validator
    const validator = control.validator({} as AbstractControl);
    return validator && validator.required;
  }
}

AppModule:

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";

import { AppComponent } from "./app.component";
import { ControlRequiredPipe } from "./control-required.pipe";

@NgModule({
  imports: [BrowserModule, FormsModule, ReactiveFormsModule],
  declarations: [AppComponent, ControlRequiredPipe],
  providers: [ControlRequiredPipe],
  bootstrap: [AppComponent]
})
export class AppModule {}

我以@Hkidd 的回答为基础。只要不更改表单验证器,该用户的回答就是正确的。这是一个不起作用的场景。

  • 5 个表单值,全部不需要
  • 使用 setValidators/updateValueAndValidity 模式
  • 根据需要选中一个值标记 2 个控件的框
  • 这 2 个控件将正确包含验证器,但不会显示星号

问题是构建的管道不会触发第二次,因为管道只将整个 FormControl 视为参数。幸运的是,这是一个简单的修复:

// HTML
Control: <strong *ngIf="form.get('control').validator | controlRequired">*</strong>
// PIPE
export class ControlRequiredPipe implements PipeTransform {
  public transform(validatorFn: ValidatorFn): boolean {
    //  Return when no control or a control without a validator is provided
    if (!validatorFn) {
      return false;
    }

    //  Return the required state of the validator
    const validator = validatorFn({} as AbstractControl) || {};
    return validator && validator.required;
  }
}