如何使用可观察对象进行数据分页?

时间:2019-04-29 22:00:19

标签: angular typescript rxjs nswag

过去的几天我一直在学习有关可观察性的知识,并已开始将它们纳入我的Angular应用程序。我有一个Web API应用程序,正在通过打字稿中的NSwagClient生成客户端。我有一个将其作为签名的API动作:

Task<ActionResult<List<Product>>> GetProducts(int skip, int take)

我在打字稿中拥有的API客户端是这样调用的:

_client.GetProductsAsync(0, 10).subscribe(next => {console.log(next)}, err => {}, () => {})

在我的脑海中,当我要求下一批产品时(因此,跳过10,取10,然后跳过20,取10),我需要更新商品的 parameters 初始_client.GetProductsAsync调用。但似乎,如果不取消订阅并重新订阅具有新参数的可观察对象,我将无法做到这一点。在我看来,这似乎与可观察性概念相反,因为它是数据流,因为应创建一次可观察性,然后以某种方式“触发”以获得更多结果并将其通过管道发送给观察者。

如何订阅一次API客户端并完成此操作?

3 个答案:

答案 0 :(得分:1)

您没有,每次检索另一页数据时,您都在发出另一个http请求。 Http请求触发一次,然后可观察对象完成。

答案 1 :(得分:1)

您将需要一个包含当前页面的Subject,并使用以下类型的RxJS运算符之一:concatMapswitchMapmergeMap

在页面Subject上施加新值时,它将触发可观察的链。

page$ = new Subject<number>();

在您的html模板中,您将需要一些内容来构建分页链接/按钮,从而在单击页面主题时将其推入新值:

<button (click)="page$.next(pageNum)">{{ pageNum }}</button>

现在,您的数据调用可以利用page$主题触发服务器发出的针对这些部分结果的新请求。页面更改后,将对您的API进行新的调用。

data$ = page$.pipe(
    map(page => (page - 1) * 10), // map to 'skip' value
    switchMap(skip => this.apiService.getProducts(skip, 10))
);

答案 2 :(得分:0)

我建立了一个名为ngx-rxcache的库,该库使您可以为Angular建立可观察的状态管理。

https://github.com/adriandavidbrand/ngx-rxcache

您可以使用product $可观察变量构建服务

@Injectable({
  providedIn: 'root'
})
export class ProductService {
  private productCache = this.cache.get<Product[]>({
    id: '[Product] products'
  });

  products$ = this.productCache.value$;

  loading$ = this.productCache.loading$;

  constructor(private http: HttpClient, private cache: RxCacheService) { }

  load(page: number) {
    this.usersCache.load(() => this.http.get<Product[]>(`product/${page}`));
  }
}

然后,您可以在组件中保持可观察的产品$订阅,并使用load方法对其进行更新。

products$ = this.productService.products$;

goto(page: number) {
  this.productService.load(page);
}

您可以在这里阅读我写的一篇文章。

https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb