Взаимная проверка поля не работает в Angular - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть два поля даты в двух отдельных компонентах.Я установил валидации на дату вступления в силу, чтобы подтвердить, если дата вступления в силу раньше даты подачи заявки.Если это раньше, чем дата приложения, должно появиться сообщение об ошибке.

Моя проблема сейчас заключается в следующем: если пользователь вводит дату приложения первым, а дату вступления в силу вторым, проверка работает нормально.Но если пользователь изменит дату приложения после ввода даты вступления в силу, проверка не сработает.Другими словами, проверка запускается только при изменении даты вступления в силу.

Как я могу сделать проверку при запуске даты вступления в силу при изменении даты приложения?Я также заметил, что когдаffectiveDate раньше даты приложения, отображается сообщение об ошибке.Затем я изменяю дату приложения на действительную, сообщение об ошибке не исчезнет.

Я попытался передать дату приложения в компонентffectiveDate.Тем не менее, он не работает, как я ожидал.

step1.component.html - это страница для вызова двух компонентов.Я передаю applicationDate $ в дочерний компонент как [minEffectiveDate] = "applicationDate $ | async".

step1.component.html , дата приложения находится внутри компонента app-internal-use.

<app-internal-use formControlName="internalUse" (brokerSearchIDResult)="addBrokerToApp($event)"
    (clientSearchIDResult)="handleClientSearchResult($event)" [shouldShowBrokerSearch]="shouldShowCommissionSplitBasedOnRoles">
  </app-internal-use>
...
<div class="col-sm-5">
  <app-plan-effective-date formControlName="effectiveDate" [submitted]="submitted" [minEffectiveDate]="applicationDate$ | async"></app-plan-effective-date>
</div>

ffectiveDate.component.html

<label>Effective Date</label>
<div class="input-group margin-xs-bottom-10" [ngClass]="{ 'has-error' : !this.control.valid && (control.touched || submitted) }">
    <input class="form-control" [formControl]="control" bsDatepicker required [minDate]="minEffectiveDate"
        #dpEffdate="bsDatepicker">
    <span class="input-group-addon datepicker-icon" (click)="dpEffdate.toggle()">
        <i class="fa fa-calendar"></i>
    </span>
</div>
<div class="errorMessage" *ngIf="control.hasError('dateNotLessThanSpecifiedDate') && (submitted || control.touched)">Effective
    date cannot be less than the application date</div>

ffectiveDate.component.ts

...
export class PlanEffectiveDateComponent extends AbstractValueAccessor implements OnInit, Validator, OnChanges {
@Input() submitted = false;
@Input() minEffectiveDate: Date;
control: FormControl;

constructor(private validatorService: ValidatorService, private cd: ChangeDetectorRef) {
    super();
}

ngOnInit() {
    this.initializeForm();
    this.handleFormChanges();
}

ngOnChanges(changes: SimpleChanges) {
    const minEffectiveDateChange = changes['minEffectiveDate'];

    if (!!minEffectiveDateChange && !minEffectiveDateChange.firstChange &&
        minEffectiveDateChange.currentValue !== minEffectiveDateChange.previousValue &&
        !!this.control) {
        this.setEffectiveDateValidator();
    }
}

initializeForm() {
    this.control = new FormControl('', this.composeEffectiveDateValidator());
}

setEffectiveDateValidator() {
    this.control.clearValidators();
    this.control.setValidators(this.composeEffectiveDateValidator());
    setTimeout(() => this.control.updateValueAndValidity({ emitEvent: false }), 0);
    this.cd.detectChanges();
}

composeEffectiveDateValidator(): ValidatorFn {
    const maxEffectiveDate = utils.currentMoment().add(6, 'month').toDate();

    return Validators.compose(
        [
            this.validatorService.dateNotGreaterThanSpecifiedDate(maxEffectiveDate),
            this.validatorService.dateNotLessThanSpecifiedDate(this.minEffectiveDate)
        ]
    );
}

handleFormChanges() {
    this.control.valueChanges.subscribe(value => {
        this.value = value;
    });
}

writeValue(value) {
    if (value) {
        this.control.setValue(value, { emitEvent: false });
    }
}

validate(control: FormControl) {
    return this.control.valid ? null : { planEffectiveDateRequired: true };
}
}

dateNotLessThanSpecifiedDate функция:

  dateNotLessThanSpecifiedDate(maxDate: Date) {
return (control: FormControl): { [key: string]: any } => {
  if (!!control.value && control.value < maxDate) {
    return { 'dateNotLessThanSpecifiedDate': true };
  } else {
    return null;
  }
};
}

Любая помощь будет оценена!

Спасибо!

1 Ответ

0 голосов
/ 26 ноября 2018

Мы поняли это с помощью ChangeDetectionStragegy.OnPush.Вот решение.

plan -ffective-date.component.ts

control = new FormControl('', this.buildValidator.bind(this));

constructor(
private cd: ChangeDetectorRef,
private controlDir: NgControl,
) {
super();
this.controlDir.valueAccessor = this;
}

ngOnInit() {
this.handleFormChanges();
this.controlDir.control.setValidators(this.validate.bind(this));
this.updateValidity();
}

updateValidity() {
setTimeout(() => {
  this.control.updateValueAndValidity();
  this.controlDir.control.setValidators(this.validate.bind(this));
  this.cd.detectChanges();
}, 0);
}

Внутри ngOnChanges вызовите updateValidity ()

ngOnChanges(changes: SimpleChanges) {
const minEffectiveDateChange = changes['minEffectiveDate'];
const currentPlanEndDateChange = changes['currentPlanEndDate'];

if ((!!minEffectiveDateChange && !minEffectiveDateChange.firstChange &&
  minEffectiveDateChange.currentValue !== minEffectiveDateChange.previousValue &&
  !!this.control) ||
  (!!this.currentPlanEndDate && !currentPlanEndDateChange.firstChange &&
    currentPlanEndDateChange.currentValue !== currentPlanEndDateChange.previousValue
    && !!this.control)) {
  this.updateValidity();
}
}

Метод buildValidator () предназначен только для установки настроенных вами валидаторов.

Надеюсь, это поможет кому-то, у кого похожая проблема со мной:)

...