【问题标题】:Angular RxJS - Need to Wait until Subscribe has finished in other methodAngular RxJS - 需要等到订阅以其他方法完成
【发布时间】:2020-05-23 11:12:14
【问题描述】:
@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' RxJs 操作符来消除抖动。

问题是我无法更新 HTML(因为我在这里简化了 HTML,但在我的项目中它是一个可折叠面板,它会导致一些我不想要的 HTML 元素消失)当我输入数据时这就是我将响应存储在临时变量“recentResponse”中并在单击“保存”按钮时更新 HTML 的原因。

但这里的问题是,如果用户输入非常快并单击“保存”按钮,订阅完成需要几秒钟,直到那时“recentResponse”未定义,因此“耐心信息”永远不会得到更新(HTML 也是如此)。

如何在 onSave() 中等待订阅完成?我需要等到 'recentResponse' 有一些响应。

【问题讨论】:

  • 您可以使用 RxJs 延迟运算符Delay,这是该运算符的常见用例之一,示例是类似的东西

标签: angular typescript rxjs observable rxjs-subscriptions


【解决方案1】:

您可以绑定到 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);
}

【讨论】:

  • OP 正在询问如何使用 RxJs 以及如何等待使用它......你的答案是使用 RxJs 吗?
  • OP 的最后两段更笼统地描述了这个问题。 rxjs 方法是解决问题的一种方法。 setTimeout 是解决问题的另一种方法。仅仅因为 rxjs 将在某个时候被使用,它并没有使它成为一个专门的 rxjs 问题。
【解决方案2】:

我建议不要在keyupkeydownkeypress 等,它会在每次按键时访问服务器,而不是 添加blur事件。

回答您的问题

方法 1 - 防止按钮点击 在 API 完成之前禁用按钮。

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

方法 2 - 可观察 将您的 API 函数包装在 observable 中并在 onSave 函数中侦听 observable 完成

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

onSave() {
 this.myApi.subscribe(() => {
  //Api is completed
 })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    相关资源
    最近更新 更多