Angular Async Validator FormControls не обновляется, пока не размыто - PullRequest
0 голосов
/ 10 июня 2019

Мой Async Validator выглядит следующим образом:

asyncValidator(service:ApiCallsService):AsyncValidatorFn{
    return (control:FormControl):Promise<ValidationErrors | null> | Observable<ValidationErrors | null> =>{
    let timer$ = timer(2000);
     return timer$.pipe(
      take(1),
      switchMap(()=> {
        let videoId = service.checkUrl(control.value);
        return service.getVideoDescription(videoId).toPromise().then((val:any)=>{

          return (!val.id) ? {"invalidUrl": true} : null;
        })
      })
    )
    }
  }

Проблема с моим Async Validator заключается в том, что мои FormControls, которые добавлены в мой FormArray, не воспринимают текущий «статус» себя, пока они не будутblurred.

Это мой FormArray и мой FormControl внутри него:

<div class="url-con" formArrayName="urls" >
    <div *ngFor="let url of urls.controls; let i=index" class="url-input-con">
        <input  minLength="5" placeholder="Video Url" class="url-input" [formControlName]="i">
        <div class="url-pending" *ngIf="urls.controls[i].pending && !urls.controls[i].valid">Validating...</div>
    </div>
</div>

Появляется div с классом "url-pending", а затем он не исчезает - даже еслиFormControl, от которого он зависит, проверяется бэкэндом - до тех пор, пока пользователь не размывает FormControl, от которого зависит div.

Единственный вопрос, подобный этому - это link .Я не мог полностью понять инструкции этой ссылки, и еще одно дополнительное усложнение, которое я испытал по сравнению с постером ссылки, заключается в том, что в моей форме есть значок в виде знака плюс, чтобы пользователь мог добавить больше FormControls в FormArray.Я не мог понять, как добавить директивы в FormControls, которые пользователь добавил, взаимодействуя с формой.

Я отвечу на свой вопрос, потому что я выяснил, как решить этот вопрос, но я решил его в«хакерский» способ.Если кто-то знает лучший ответ на этот вопрос, пожалуйста, ответьте.

1 Ответ

0 голосов
/ 10 июня 2019

Я добавил идентификатор в formArray (#formArray):

<div #formArray class="url-con" formArrayName="urls" >
    <div *ngFor="let url of urls.controls; let i=index" class="url-input-con">
        <input  minLength="5" placeholder="Video Url" class="url-input" [formControlName]="i">
        <div class="url-pending" *ngIf="urls.controls[i].pending && !urls.controls[i].valid">Validating...</div>
    </div>
</div>

Затем я добавил finalize () к возвращению timer $ в Async Validator.Внутри обратного вызова оператора я сделал каждый FormControl из фокуса FormArray, а затем размыл.

asyncValidator(service:ApiCallsService):AsyncValidatorFn{
   return (control:FormControl):Promise<ValidationErrors | null> | Observable<ValidationErrors | null> =>{
   let timer$ = timer(2000);
    return timer$.pipe(
     take(1),
     switchMap(()=> {
       let videoId = service.checkUrl(control.value);
       return service.getVideoDescription(videoId).toPromise().then((val:any)=>{

         return (!val.id) ? {"invalidUrl": true} : null;
       })
     }),
     finalize(()=>{
         Array.from(this.formArray.nativeElement.children)
              .forEach((val:HTMLElement,ind)=>{
                   (Array.from(val.children)[0] as HTMLElement).focus();
                   (Array.from(val.children)[0] as HTMLElement).blur();
               })         
     })
   )
}
}

Каждый FormControl должен быть вначале сфокусирован, потому что, если пользователь размывается до завершения проверки, тогда FormControl никогда не размываетсяи состояние «ожидания» сохраняется на дисплее навсегда (но не функционально).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...