首页 > 解决方案 > 使用 RxJS 的 Angular 数据服务

问题描述

我正在编写一个 Angular 应用程序,它与类似 REST 的后端通信。

UI 由一个主/详细页面组成,其中一个元素可以在左侧选择,详细信息显示在右侧。使用角路由器,路由器插座等。

可选项目显示详细信息的摘要。编辑详细项目时,我想用更新的信息更新可选项目。

我有一个 api 服务,它使用 HttpClient 从后端获取值。

api.service.ts

public getAllItems(): Observable<Item[]> {
return this.http.get<Item[]>(this.apiUrl + '/items')
  .map(response => {
    return response.map((item) => new Item(item));
  });
}

我还有一个数据服务,它目前只是从 api 服务返回 observable。

项目-data.service.ts

get items$(): Observable<Item[]> {
  return this.api.getAllItems();
}

主(左侧)组件仅注册可观察的数据服务。

item-master.component.ts

data$: Observable<Item[]>;

constructor(private itemsDataService: ItemsDataService) { }

ngOnInit() {
  this.data$ = this.itemsDataService.items$;
}

该模板使用异步管道并迭代数组以显示摘要。

item-master.component.html

<div *ngIf="(data$ | async) as data">

使用此方法,当应用程序中的项目更新时,可选项目不会自动更新。

现在,我正在考虑更改数据服务,以便我有一个可以观察到的内部主题。当通过数据服务中的方法执行更新时,我可以调用 subject.next() 来通知更改。但是这个应用程序也被其他机器/浏览器上的其他人同时使用。

理想情况下,我想从后端重新获取数据,但是 Subject 将有效地充当“缓存”,仅触发对 api 的第一次调用。如何最有效地确保从后端获取最新数据并从本地所做的更改中获取更新?

标签: angulararchitecturerxjsdataservice

解决方案


假设我的问题是正确的,我会将服务更改为这样的(这是一个非常示意性的描述):

items$: Observable<Array<Item>>;

currentItemId$ = new Subject<String>();

currentItem$: Observable<Item> = this.currentItemId$.map(<your fetch code>);

loadItem(itemId) {
  this.currentItemId$.next(itemId);
}

每当您单击主视图中的某个项目时,它将调用loadItem()将获取特定值并将其通过管道传递给currentItem$.

这为您提供了一种更加面向服务(带有商店)的方法,这意味着,您告诉它加载一个项目并在暴露的 observable 上使用该项目


推荐阅读