Angular2 和 RxJS 多个 HTTP 调用 - 返回第一个响应后立即显示

Angular2 & RxJS multiple HTTP calls - display as soon as first response returned

我正在尝试使用 RxJS 和 Angular2 构建搜索字段。我有一个简单的文本输入字段,我正在观察它的 valueChanges。

然后我使用输入的值调用第一个 REST 服务,该服务returns 一个包含客户列表的搜索结果对象。

然后,对于每个返回的客户,我调用第二个 REST 服务来获取客户详细信息并将返回的详细信息存储在客户对象中。

我的屏幕然后循环显示客户。

但我有两个问题似乎无法弄清楚:

  1. 我希望在第一次服务时立即显示结果 returns 然后在第二个服务 returns 但在 在所有服务呼叫完成之前什么都没有显示 完全的。
  2. 当有人更改输入字段时,我希望结果消失 立即但由于某种原因没有发生而且我不能 弄清楚为什么如果我输入 returns 否的搜索词 匹配,之前搜索的结果将保留在屏幕上。

我的代码如下:

this.customers = this.term.valueChanges
            .filter(term => {
                return term !== null;
            })
            .switchMap(term => {
                return this.customerService.search(term)
            })
            .map(searchResults => {
                return searchResults.customers;
            })
            .flatMap(customers => {
                if (customers.length > 0) {
                    // this.customers = customers;
                    return Observable.forkJoin(
                        customers.map((customer: Customer) => {
                            return this.customerDetailService.getDetails(customer)
                                .map((details: any) => {
                                    customer.details = details;
                                    return customer;
                                });
                        }));
                }
                return customers;
            });

屏幕看起来像:

<div *ngIf="customers|async; let customers">

    <ul>
        <li *ngFor="let customer of customers">

           {{customer.name}}
           {{customer.details.age}}
        </li>
    </ul>
</div>

如有任何帮助,我们将不胜感激。

谢谢, 凯文.

什么是this.customers?初始提取和以后的每个更新的组合。所以这应该有效:

let search = this.term.valueChanges
  .filter(term => term !== null)
  .switchMap(term => this.customerService.search(term))
  .map(searchResults => searchResults.customers);

let details = search.switchMap(customers => {
  if (customers.length > 0) {
    // this.customers = customers;
    return Observable.forkJoin(
      customers.map((customer: Customer) => {
        return this.customerDetailService.getDetails(customer)
          .map((details: any) => {
            customer.details = details;
            return customer;
          });
      }));
  }
  return customers;
});

this.customers = Observable.merge(search, details);

这个呢? (后面的解释看我对你问题的评论)

this.customers = new Rx.BehaviourSubject([]);

this.term.valueChanges
    .filter(term =>  term !== null)
    .do(() => this.customers.onNext([]))
    .switchMap(term => this.customerService.search(term))
    .map(searchResults => searchResults.customers)
    .do((customers) => this.customers.onNext(customers))
    .switchMap(customers => {
        if (customers.length > 0) {
            // this.customers = customers;
            return Observable.forkJoin(
                customers.map((customer: Customer) => {
                    return this.customerDetailService.getDetails(customer)
                        .map((details: any) => {
                            customer.details = details;
                            return customer;
                        });
                }));
        }
        return customers;
    })
    .subscribe(
        (customers) => this.customers.onNext(customers),
        (err) => this.customers.onError(err),
        () => this.customers.onComplete();
    );