如何使用反应形式在 Angular 7 中设置 "At least one field should be filled out" 验证?
How to set "At least one field should be filled out" validation in Angular 7 with reactive forms?
我在 angular 7 中有一个反应式表单,它具有三个字段电子邮件、phone 和寻呼机。我的要求是用户至少应该填写其中一项,否则我们应该抛出这样的错误 "Please specify one of the notifications (Email, SMS or Pager)."
我试过编写自定义通知,但它不起作用。你能帮我看看我错在哪里吗?
下面是我的 HTML 代码:
<form class="form-horizontal" [formGroup]="editorForm">
<div class="form-group" required>
<label for="emailAdressInput">Email Addresses</label>
<input type="text" id="emailAdressInput" formControlName="emailAdresses">
</div>
<div class="form-group" required>
<label for="phoneNumberInput">Email Addresses</label>
<input type="text" id="phoneNumberInput" formControlName="phoneNumber">
</div>
<div class="form-group" required>
<label for="pagerNumberInput">Email Addresses</label>
<input type="text" id="pagerNumberInput" formControlName="pagerNumber">
</div>
</form>
下面是component.ts代码:
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
}, this.atLeastOneValidator()),
pagerNumber: [''],
});
public atLeastOneValidator = () => {
return (controlGroup) => {
let controls = controlGroup.controls;
if ( controls ) {
let theOne = Object.keys(controls).find(key=> controls[key].value!=='');
if ( !theOne ) {
return {
atLeastOneRequired : {
text : 'At least one should be selected'
}
}
}
}
return null;
};
};
atLeastOneValue(form: FormGroup): ValidationErrors {
return Object.keys(form.value).some(key => !!form.value[key]) ?
null :
{ atLeastOneRequired : 'At least one should be selected' };
}
并通过
调用
builder.group({...}, [this.atLeastOneValue]);
我已经在 stackblitz 中解决了:https://stackblitz.com/edit/angular-j3i4yg
export class AppComponent {
name = 'Angular';
editorForm: FormGroup;
// _formBuilder: FormBuilder = new FormBuilder();
constructor(private _formBuilder: FormBuilder) {
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
}, { validators: this.atLeastOneValidator }),
pagerNumber: [''],
});
}
public atLeastOneValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
let controls = control.controls;
console.log(controls);
if (controls) {
let theOne = Object.keys(controls).findIndex(key => controls[key].value !== '');
if (theOne === -1) {
console.log(theOne);
return {
atLeastOneRequired: {
text: 'At least one should be selected'
}
}
}
};
}
}
模板:
<form class="form-horizontal" [formGroup]="editorForm">
<fieldset formGroupName="notification">
<div class="form-group" required>
<label for="emailAdressInput">Email Addresses</label>
<input type="text" id="emailAdressInput" formControlName="emailAdresses">
</div>
<div class="form-group" required>
<label for="phoneNumberInput">Email Addresses</label>
<input type="text" id="phoneNumberInput" formControlName="phoneNumber">
</div>
<div class="form-group" required>
<label for="pagerNumberInput">Email Addresses</label>
<input type="text" id="pagerNumberInput" formControlName="pagerNumber">
</div>
</fieldset>
{{editorForm.get('notification')?.errors| json}}
<br>
<br>
<span *ngIf="editorForm.get('notification')?.errors?.atLeastOneRequired"> {{editorForm.get('notification')?.errors?.atLeastOneRequired.text}}</span>
</form>
如果您有任何疑问,请检查并告诉我。
为了指示在表单组中使用 formBuilder 的验证器正在添加 {validators:yourValidator}
group(controlsConfig: { [key: string]: any; }, options: AbstractControlOptions | { [key: string]: any; } = null)
在文档中查看 AbstractControlOptions
(如果要创建一个formControl,可以直接添加validator)
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
},{ validators:this.atLeastOneValidator()}), //<--THIS
pagerNumber: [''],
});
}
此外,您在 .html
中忘记了一个 <div formGroupName="notification">
无论如何,我建议不要使用 formBuilder,您可以使用 form group 和 formControl 的构造函数,例如
this.editorForm = new FormGroup({
displayLabel: new FormControl('', Validators.required),
emailAdresses: new FormControl(''),
phoneNumber: new FormControl(''),
notification: new FormGroup({
pagerNumber: new FormControl(''),
phoneNumber: new FormControl(''),
emailAdresses: new FormControl('')
},this.atLeastOneValidator()),
pagerNumber: new FormControl(),
});
}
我在 angular 7 中有一个反应式表单,它具有三个字段电子邮件、phone 和寻呼机。我的要求是用户至少应该填写其中一项,否则我们应该抛出这样的错误 "Please specify one of the notifications (Email, SMS or Pager)."
我试过编写自定义通知,但它不起作用。你能帮我看看我错在哪里吗?
下面是我的 HTML 代码:
<form class="form-horizontal" [formGroup]="editorForm">
<div class="form-group" required>
<label for="emailAdressInput">Email Addresses</label>
<input type="text" id="emailAdressInput" formControlName="emailAdresses">
</div>
<div class="form-group" required>
<label for="phoneNumberInput">Email Addresses</label>
<input type="text" id="phoneNumberInput" formControlName="phoneNumber">
</div>
<div class="form-group" required>
<label for="pagerNumberInput">Email Addresses</label>
<input type="text" id="pagerNumberInput" formControlName="pagerNumber">
</div>
</form>
下面是component.ts代码:
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
}, this.atLeastOneValidator()),
pagerNumber: [''],
});
public atLeastOneValidator = () => {
return (controlGroup) => {
let controls = controlGroup.controls;
if ( controls ) {
let theOne = Object.keys(controls).find(key=> controls[key].value!=='');
if ( !theOne ) {
return {
atLeastOneRequired : {
text : 'At least one should be selected'
}
}
}
}
return null;
};
};
atLeastOneValue(form: FormGroup): ValidationErrors {
return Object.keys(form.value).some(key => !!form.value[key]) ?
null :
{ atLeastOneRequired : 'At least one should be selected' };
}
并通过
调用builder.group({...}, [this.atLeastOneValue]);
我已经在 stackblitz 中解决了:https://stackblitz.com/edit/angular-j3i4yg
export class AppComponent {
name = 'Angular';
editorForm: FormGroup;
// _formBuilder: FormBuilder = new FormBuilder();
constructor(private _formBuilder: FormBuilder) {
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
}, { validators: this.atLeastOneValidator }),
pagerNumber: [''],
});
}
public atLeastOneValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
let controls = control.controls;
console.log(controls);
if (controls) {
let theOne = Object.keys(controls).findIndex(key => controls[key].value !== '');
if (theOne === -1) {
console.log(theOne);
return {
atLeastOneRequired: {
text: 'At least one should be selected'
}
}
}
};
}
}
模板:
<form class="form-horizontal" [formGroup]="editorForm">
<fieldset formGroupName="notification">
<div class="form-group" required>
<label for="emailAdressInput">Email Addresses</label>
<input type="text" id="emailAdressInput" formControlName="emailAdresses">
</div>
<div class="form-group" required>
<label for="phoneNumberInput">Email Addresses</label>
<input type="text" id="phoneNumberInput" formControlName="phoneNumber">
</div>
<div class="form-group" required>
<label for="pagerNumberInput">Email Addresses</label>
<input type="text" id="pagerNumberInput" formControlName="pagerNumber">
</div>
</fieldset>
{{editorForm.get('notification')?.errors| json}}
<br>
<br>
<span *ngIf="editorForm.get('notification')?.errors?.atLeastOneRequired"> {{editorForm.get('notification')?.errors?.atLeastOneRequired.text}}</span>
</form>
如果您有任何疑问,请检查并告诉我。
为了指示在表单组中使用 formBuilder 的验证器正在添加 {validators:yourValidator}
group(controlsConfig: { [key: string]: any; }, options: AbstractControlOptions | { [key: string]: any; } = null)
在文档中查看 AbstractControlOptions
(如果要创建一个formControl,可以直接添加validator)
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
},{ validators:this.atLeastOneValidator()}), //<--THIS
pagerNumber: [''],
});
}
此外,您在 .html
中忘记了一个<div formGroupName="notification">
无论如何,我建议不要使用 formBuilder,您可以使用 form group 和 formControl 的构造函数,例如
this.editorForm = new FormGroup({
displayLabel: new FormControl('', Validators.required),
emailAdresses: new FormControl(''),
phoneNumber: new FormControl(''),
notification: new FormGroup({
pagerNumber: new FormControl(''),
phoneNumber: new FormControl(''),
emailAdresses: new FormControl('')
},this.atLeastOneValidator()),
pagerNumber: new FormControl(),
});
}