(Angular 12) 仅当具有 http 调用的方法执行完毕后,按钮单击才应继续进行

问题描述 投票:0回答:1

有一个搜索功能,用户可以在表单中输入多个搜索条件,然后单击搜索按钮,搜索操作开始。

此搜索条件表单中很少有下拉字段。在下拉列表中选择一个值会触发 API 调用以获取特定 ID,该 ID 将在请求负载的查询中传递以获取搜索结果。

API调用是通过一定的方法进行的,搜索点击是单独的方法。 结构如下所示 -

/**
 * Method to capture changes in the form
 */
valueChanges(control, change) {
    if (control === TYPE1) {
        // update the search query
    } else if (control === TYPE2) {
        // get the ID by making API call
        this.getID()
    }
}

/**
 * Method to get certain ID
 */
private getId() {
    this.http.get(url, params).subscribe(res => {
        const formValue = this.reactiveForm.value
        // id fetched and saved to form value
        formValue['id'] = res.content.id
        // update the search query
    })
}

/**
 * Method to start search operation by making another API call
 */
public performSearch() {
    this.http.post(url, params).subscribe(res => {
        // get search results
    })
}

当用户在选择触发 API 调用的下拉值后立即单击“搜索”按钮时,就会出现问题。这样的话,获取ID的API还没有结束,search()方法会执行。

如何避免这种情况?

P.S. 禁用该按钮是我的最后一个选择。我在这里寻找一些更好的选择。

angular asynchronous search
1个回答
0
投票

您可以添加一个标志变量来保存

getId
方法的状态,并等待它完成。

您可以使用

BehaviorSubject
,并从
getId
方法切换状态,然后在搜索按钮单击事件上的新
prepareSearch
方法中订阅它,并使用
takeWhile
阻止处理,直到完成。

尝试一下,

isApiLoading$
的初始值设置为
false
,表示它没有执行请求,当执行时,它会从
true
方法将值更改为
getId
,直到请求完成,然后将其设置回
false

当点击按钮时,

prepareSearch
方法将获取最新值,如果为假,则执行请求,否则等待
getId
完成:

private isApiLoading$ = new BehaviorSubject<boolean>(false);

/**
 * perform search only when getId is done
 */
public prepareSearch() {
    
    this.isApiLoading$
      .pipe(
        // block pefrom search until getId() is done
        takeWhile((val) => !!val)
      )
      .subscribe(
        (val) => console.log(val),
        (err) => console.log(err),
        // getId() done or not performing, now call performSearch()
        () => this.performSearch()
      );
  }

    
/**
 * Method to get certain ID
 */
private getId() {

    // block peform search
    this.isApiLoading$.next(true);

    this.http.get(url, params).subscribe(res => {
        const formValue = this.reactiveForm.value
        // id fetched and saved to form value
        formValue['id'] = res.content.id
        // update the search query

        // unblock perform search 
        this.isApiLoading$.next(false);

    })
}  
© www.soinside.com 2019 - 2024. All rights reserved.