0

我正在为我的组件实现 ControlValueAccessor,并且我在表单中有许多可以更改的日期范围。

我创建了一个自定义验证器,用于检查日期范围之间的任何重叠:

test.component.html

<ng-container *ngIf="value as v">
  <form  rangeValidator [ranges]="v.ranges"  #dateForm="ngForm" >
   <div  *ngFor="let x of v.ranges;let index = index;trackBy:trackIndex;">
        <input type="date" [(ngModel)]="x.start" #start='ngModel' name="start-{{index}}">
        <input type="date" [(ngModel)]="x.end" #end='ngModel' name="end-{{index}}">
        <button (click)="removeRange(index)">
          <mat-icon>delete</mat-icon>
        </button>
    </div>
</form>
</ng-container>

测试组件.ts

@ViewChild('dateForm') dateForm;
@Output('onValidChange') onValidChange: EventEmitter<boolean | Boolean> = new EventEmitter<boolean | Boolean>();

writeValue(obj): void {
    this.value = obj;
  }

  onChange = (_) => { };
  onTouched = () => { };
  registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
  registerOnTouched(fn: () => void): void { this.onTouched = fn; }


  private _value= {};
  public get value(){
    if (this.dateForm!== undefined){
      this.dateForm.valueChanges.subscribe(values => {
        this.onValidChange.next(this.dateForm.valid);
// this is emitting validity to the parent component, which then disables the submit button based on it.
      })
  } 
    return this._value;
  }
  public set value(v) {
    this._value = v;
    this.onChange(v);
  }

dateRange.validator.directive.ts

import {  NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';   

   import { Directive, Input } from '@angular/core';
@Directive({  
  selector: '[rangeValidator]',  
  providers: [  
   {  
    provide: NG_VALIDATORS,  
    useExisting: RangeValidator,  
    multi: true  
   }  
  ]  
 })

 export class RangeValidator implements Validator {
    @Input() ranges;
    public constructor() {}

    validate(formGroup): {  } | null {
          //code to perform overlapping logic
          if (overlapped) {
            return {
               overlapping: true
           }
          } else {
            return null;
          }
         }
       }
      }  

验证逻辑工作正常,但有效性是根据之前的表单值反映的。例如,如果我输入了重叠的值,表格保持有效,然后我删除了重叠,表格将变为无效。即使验证器正在接收最新的值。知道为什么它不能立即反映正确的有效性吗?

4

0 回答 0