Angular Rx JS - нужно дождаться окончания подписки другим способом - PullRequest
1 голос
/ 07 февраля 2020
@Component({
  selector: 'note-consultant',
  template: '<div>
    <div>{{patientInformation}}</div>
    <textarea #textElemRef></textarea>
    <button (click)="onSave()">Done</button>
    </div>'
})
export class NoteConsultantComponent implements OnInit, AfterViewInit { 
    recentResponse:any;
    patientInformation:any;
    @ViewChild('textElemRef') textElemRef: ElementRef;

    ngAfterViewInit(): void {
    fromEvent(this.textElemRef.nativeElement, 'keyup').pipe(
      map((event: any) => {
        return event.target.value;
      })
      ,debounceTime(1000)
    ).subscribe((text: string) => {

      let request = this.buildRequestItem(text);
        this.patientService.saveProblemNotes(request).subscribe((resp: any) => {
            if (resp.error) {
              console.log(resp.error);
              return;
            }

            //update response in temp variable...
            this.recentResponse = resp.problemText;
            }
        });
    }
    onSave() {
       if (this.recentResponse != null) {    
       //when clicking save button update DOM
       this.patientInformation = this.recentResponse;
     }

      //Reset temp variable
      this.recentResponse = null;
    }
}

У меня есть сценарий, когда пользователь вводит текст, я должен нажать API и сохранить введенные данные. Как будет неэффективно нажимать API для каждого нажатия клавиши. поэтому я использовал оператор fromEvent Rx Js для отладки на секунду.

Дело в том, что я не могу обновить HTML (потому что я упростил HTML здесь, но в моем проекте это складная панель, она приведет к исчезновению нескольких элементов HTML, которые мне не нужны), когда я печатаю данные. Поэтому я и сохраняю ответ во временной переменной RecentResponse, и после нажатия кнопки «Сохранить» я обновляю * 1013. *.

Но проблема здесь в том, что если пользователь очень быстро печатает и нажимает кнопку «Сохранить», до завершения подписки требуется несколько секунд, до тех пор, пока «RecentResponse» не определен, поэтому «PatientInformation» никогда не получает обновления (как и HTML).

Как мне дождаться окончания подписки внутри onSave ()? Мне нужно подождать, пока «RecentResponse» получит ответ.

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Я бы посоветовал не вызывать API для таких событий, как keyup, keydown, keypress и т. Д. c. Он будет попадать на сервер при каждом нажатии клавиши. Вместо этого добавьте событие blur.

Чтобы ответить на ваш вопрос

Метод 1 - Запрет нажатия кнопки Просто отключите кнопку, пока API не будет завершен.

fromEvent().subscribe(() => {
 disableBtn = true;
 this.patientService.saveProblemNotes(request).subscribe(() => {
  disableBtn = false; 
 })
})

Метод 2 - Наблюдаемый Оберните вашу API-функцию в наблюдаемую и прослушайте наблюдаемую завершенную в onSave функцию

myApi() {
 new Observable(observer => {
  this.patientService.saveProblemNotes(request).subscribe(() => {
   observer.next();
  });
 });
}

onSave() {
 this.myApi.subscribe(() => {
  //Api is completed
 })
}
1 голос
/ 07 февраля 2020

Вы можете привязаться к событию keyup и использовать javascript тайм-аут, чтобы отложить выполнение до остановки набора.

html

<input type="text" (keyup)="onKeyUp($event)" />

машинопись

timeout: number;

onKeyUp(event): void {
  if (this.timeout) {
    window.clearTimeout(this.timeout);
  }

  this.timeout = window.setTimeout(() => {
    // TODO: process key up here
  }, 500);
}
...