如果需要,请检查Angular FormControl



是否有方法检查是否需要控制?

当我实现一个专用的表单字段组件时,出现了这个问题,该组件接受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

这将返回一个Object,其中包含FormControl上存在的验证器列表。然后,您可以在对象中检查required键。如果它存在并且其值为true,则可以确保在FormControl上应用了Required Validator。


这是工作样品StackBlitz供您参考。

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

在您的.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>

我玩游戏有点晚了,但我认为这可以通过使用Pipe来解决。上面的答案解决了你的问题,但有一点需要注意。通过在模板中直接使用方法/ggetter,可以在每次运行更改检测时执行此函数,如本文所述。在您的简短示例中,这可能不是性能问题,但在较大的形式中可能是一个问题。

我的解决方案

通过使用纯管道,一旦管道的输入值发生更改,就会激发对所提供控件的检查。我已经将ControlRequiredPipe添加到AppModuleprovidersdeclarations部分中。当管道被添加到providers部分时,它也可以在ComponentTypeScript类中使用。我已经在AppComponentOnSubmit函数中包含了这种行为。

堆栈闪电战示例

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 {}

根据这个Angular文档,您可以使用hasValidator方法来检查控件中是否使用了内置验证器。

let abstractControl = this.formGroup.controls[this.formControlName];
const isRequired = abstractControl.hasValidator(Validators.required);

我正在构建@Hkidd的答案。只要表单验证器没有更改,此用户的回答就是正确的。这是一个不起作用的场景。

  • 5个表单值,全部不需要
  • 选中其中一个值的框,根据需要使用setValidators/updateValueAndValidity模式标记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;
}
}

您可以使用所需的属性。

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

此外,它对CSS样式或可访问性很有帮助。

最新更新