反应式验证 Angular 5:编写用于比较两个控件的自定义验证器
Reactive Validation Angular 5: Writing Custom validator for comparing two controls
我希望仅在验证失败时禁用我的保存按钮...
验证 1:开始时间 < 结束时间
Validation2 :两者都为空或都有数据(已经在 24hr-hh:mm 中)。
我的实施-
1..ts文件:
private createForm() {
this.commentForm = new FormGroup({
'startTime': new
FormControl(this.startTime,
[
this.openCloseTimeValidator
]),
'endTime': new
FormControl(this.endTime, [
this.openCloseTimeValidator
]),});
}
openCloseTimeValidator(control: FormControl) {
const commentFormGroup = control.root;
const startTime = ((commentFormGroup.get('startTime')) ?
commentFormGroup.get('startTime').value : null);
const endTime = ((commentFormGroup.get('endTime')) ?
commentFormGroup.get('endTime').value : null);
return startTime && endTime && (startTime >= endTime) ?
{ 'openCloseTimeValidator' : true } : null;
}
- .html 文件
<form [formGroup]="commentForm">
<div formGroupName="noiseOrdinance">
<div fxFlex class= "time-picker">
<time-picker placeholder="Start Time"
formControlName="startTime" type="text"></time-picker>
</div>
<div fxFlex class= "time-picker">
<time-picker placeholder="End Time" formControlName="endTime"
type="text"></time-picker>
</div>
</div>
<button mat-button [disabled]="!commentForm.valid">Save</button>
</form>
此验证工作不正常,请考虑以下情况:最初 startTime< endTime,现在将 endTime 减小到小于 startTime,然后再次使 startTime 小于 EndTime。---> 保存将被禁用,但它的错了应该是有能力的状态。
如果选中和取消选中包含在复选框中的 html-snippet,验证值会更新。但
在控制台日志上:我得到 ExpressionChangedAfterItHasBeenCheckedError
您可以通过其他方式实现相同的目的,即使用 ngmodel 和 ngModelChange:
举个例子:
在你的 HTML、
在两个<time-picker>
标签中连续添加这两个
[(ngModel)]="searchTimeIni" (ngModelChange)=checkValid()
[(ngModel)]="searchTimeFin" (ngModelChange)=checkValid()
按钮标记为
<button mat-button [disabled]="!valid">Save</button>
TS文件中
valid: boolean = false;
checkValid() {
if (this.searchTimeIni=== undefined && this.searchTimeFin=== undefined) {
this.valid = false;
}
else if (this.searchTimeIni< this.searchTimeFin) {
this.valid = true;
}
else if (this.searchTimeIni> this.searchTimeFin) {
this.valid = false;
}
}
在您的描述中,您提到验证应该是 startTime < endTime
,但您在验证器中键入的是 startTime && endTime && (startTime >= endTime)
。
无论如何,您的验证器可能如下所示:
import { Component } from '@angular/core';
import { FormControl, ValidatorFn, FormGroup, FormBuilder } from '@angular/forms';
const timeValidator: ValidatorFn = (ctrl: FormGroup) => {
const start = ctrl.get('startTime').value;
const end = ctrl.get('endTime').value;
return start && end && start < end ? null : { 'timeError': true };
}
@Component({
selector: 'my-app',
template: `
<form [formGroup]="form">
<input type="number" formControlName="startTime" />
<input type="number" formControlName="endTime" />
</form>
Valid: {{ form.valid }}
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;
// pretend it's epoch time
startTime = 1000;
endTime = 2000;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
startTime: [this.startTime],
endTime: [this.endTime],
}, { validator: timeValidator })
}
}
我希望仅在验证失败时禁用我的保存按钮... 验证 1:开始时间 < 结束时间 Validation2 :两者都为空或都有数据(已经在 24hr-hh:mm 中)。 我的实施- 1..ts文件:
private createForm() {
this.commentForm = new FormGroup({
'startTime': new
FormControl(this.startTime,
[
this.openCloseTimeValidator
]),
'endTime': new
FormControl(this.endTime, [
this.openCloseTimeValidator
]),});
}
openCloseTimeValidator(control: FormControl) {
const commentFormGroup = control.root;
const startTime = ((commentFormGroup.get('startTime')) ?
commentFormGroup.get('startTime').value : null);
const endTime = ((commentFormGroup.get('endTime')) ?
commentFormGroup.get('endTime').value : null);
return startTime && endTime && (startTime >= endTime) ?
{ 'openCloseTimeValidator' : true } : null;
}
- .html 文件
<form [formGroup]="commentForm">
<div formGroupName="noiseOrdinance">
<div fxFlex class= "time-picker">
<time-picker placeholder="Start Time"
formControlName="startTime" type="text"></time-picker>
</div>
<div fxFlex class= "time-picker">
<time-picker placeholder="End Time" formControlName="endTime"
type="text"></time-picker>
</div>
</div>
<button mat-button [disabled]="!commentForm.valid">Save</button>
</form>
此验证工作不正常,请考虑以下情况:最初 startTime< endTime,现在将 endTime 减小到小于 startTime,然后再次使 startTime 小于 EndTime。---> 保存将被禁用,但它的错了应该是有能力的状态。
如果选中和取消选中包含在复选框中的 html-snippet,验证值会更新。但 在控制台日志上:我得到 ExpressionChangedAfterItHasBeenCheckedError
您可以通过其他方式实现相同的目的,即使用 ngmodel 和 ngModelChange:
举个例子:
在你的 HTML、
在两个<time-picker>
标签中连续添加这两个
[(ngModel)]="searchTimeIni" (ngModelChange)=checkValid()
[(ngModel)]="searchTimeFin" (ngModelChange)=checkValid()
按钮标记为
<button mat-button [disabled]="!valid">Save</button>
TS文件中
valid: boolean = false;
checkValid() {
if (this.searchTimeIni=== undefined && this.searchTimeFin=== undefined) {
this.valid = false;
}
else if (this.searchTimeIni< this.searchTimeFin) {
this.valid = true;
}
else if (this.searchTimeIni> this.searchTimeFin) {
this.valid = false;
}
}
在您的描述中,您提到验证应该是 startTime < endTime
,但您在验证器中键入的是 startTime && endTime && (startTime >= endTime)
。
无论如何,您的验证器可能如下所示:
import { Component } from '@angular/core';
import { FormControl, ValidatorFn, FormGroup, FormBuilder } from '@angular/forms';
const timeValidator: ValidatorFn = (ctrl: FormGroup) => {
const start = ctrl.get('startTime').value;
const end = ctrl.get('endTime').value;
return start && end && start < end ? null : { 'timeError': true };
}
@Component({
selector: 'my-app',
template: `
<form [formGroup]="form">
<input type="number" formControlName="startTime" />
<input type="number" formControlName="endTime" />
</form>
Valid: {{ form.valid }}
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;
// pretend it's epoch time
startTime = 1000;
endTime = 2000;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
startTime: [this.startTime],
endTime: [this.endTime],
}, { validator: timeValidator })
}
}