【发布时间】:2017-05-07 10:57:38
【问题描述】:
我有一个包含 2 个日期时间选择器组件的表单的父组件,它们是 formControls。这些代表 startDate 和 endDate。
我还有 2 个自定义验证器指令用于这 2 个表单控件。一是检查给定的输入日期是否小于控件的日期。另一个检查给定的输入日期是否大于控件的日期。
这 2 个验证器允许我验证 startDate 和 endDate 的以下条件:
- startDate 和 endDate 必须在将来(比现在晚)
- startDate 必须在 endDate 之前
所以,我的问题是,当我更新其中一个日期时,验证只会发生在我更新的日期。例如:
- 我将 startDate first 设置为一个有效的未来日期。
- 我将 endDate 设置在 startDate 之前。这会使 endDate 无效。
- 我将 startDate 更改为 endDate 之前的有效未来日期。 我希望 endDate 生效,即使 startDate 发生了变化。
我的问题是:如何优雅地使有效性在另一个控件上运行?
父组件模板:
<form #projectForm="ngForm" novalidate class="row">
<div class="form-group col-md-6">
<label for="startDate">Start Date</label>
<date-time-picker #startDate="ngModel" name="startDate" [(ngModel)]="project.startDate" [disabled]="isReadOnly" [dateLessThan]="project.endDate" [dateGreaterThan]="now"></date-time-picker>
<div *ngIf="startDate.errors">
<div [hidden]="startDate.valid" *ngIf="startDate.errors.dateLessThan" class="alert alert-danger">Start date should be before end date</div>
<div [hidden]="startDate.valid" *ngIf="startDate.errors.dateGreaterThan" class="alert alert-danger">Date should be in the future</div>
</div>
</div>
<div class="form-group col-md-6">
<label for="endDate">End Date</label>
<date-time-picker #endDate="ngModel" name="endDate" [(ngModel)]="project.endDate" [disabled]="isReadOnly" [dateGreaterThan]="maxDate()"></date-time-picker>
<div *ngIf="endDate.errors">
<div [hidden]="endDate.valid" *ngIf="endDate.errors.dateGreaterThan" class="alert alert-danger">End date is too early</div>
</div>
</div>
</div>
</div>
date-less-that-validator.directive.ts:
import { Directive, forwardRef, Input } from '@angular/core';
import { NG_VALIDATORS, FormControl } from '@angular/forms';
import * as moment from 'moment';
/**
* Directive to validate whether FormControl's date is less than input date
*/
@Directive({
selector: '[dateLessThan][ngModel],[dateLessThan][formControl]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => DateLessThanValidatorDirective), multi: true }
]
})
export class DateLessThanValidatorDirective {
validator: Function;
constructor() { //If validating onEndDate, reverse the otherDate
this.validator = this.dateLessThan();
}
@Input('dateLessThan') inputDate: Date; // Date comparing against.
validate(c: FormControl) {
return this.validator(c);
}
/**
* Factory method that creates a function that accepts a form control.
* Returns null if form is valid. Returns an object that contains error message if invalid.
*/
dateLessThan() {
return (c: FormControl) => {
let controlDate = c.value;
if (controlDate && this.inputDate) { //Only if both dates are set do we do validation
if (moment(controlDate).diff(this.inputDate) > 0) {
return {
dateLessThan: 'Controls date is greater than given date'
};
}
}
return null;
};
}
}
日期大于验证器.directive.ts:
import { Directive, forwardRef, Input } from '@angular/core';
import { NG_VALIDATORS, FormControl } from '@angular/forms';
import * as moment from 'moment';
/**
* Directive to validate whether FormControl's date is greater than input date
*/
@Directive({
selector: '[dateGreaterThan][ngModel],[dateGreaterThan][formControl]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => DateGreaterThanValidatorDirective), multi: true }
]
})
export class DateGreaterThanValidatorDirective {
validator: Function;
constructor() { //If validating onEndDate, reverse the otherDate
this.validator = this.dateGreaterThan();
}
@Input('dateGreaterThan') inputDate: Date; // Date comparing against.
validate(c: FormControl) {
return this.validator(c);
}
/**
* Factory method that creates a function that accepts a form control.
* Returns null if form is valid. Returns an object that contains error message if invalid.
*/
dateGreaterThan() {
return (c: FormControl) => {
let controlDate = c.value;
if (controlDate && this.inputDate) { //Only if both dates are set do we do validation
if (moment(controlDate).diff(this.inputDate) < 0) {
return {
dateGreaterThan: 'Controls date is less than given date'
};
}
}
return null;
};
}
}
【问题讨论】:
标签: angular angular2-template angular2-forms