Angular - 如何正确使用 Services、HttpClient 和 Observables 在我的应用程序中传递对象数组

标签 angular typescript rxjs observable httpclient

我一直在努力理解这一点,并且很多示例都讨论了 Observables 或 HttpClient,但没有同时讨论两者(至少不是我的想法)。

我有一个来自数据库的类别集合。这些类别有一些属性,并在我的应用程序中的多个不同组件中使用。

export class Category {
    public Id: string = null;
    public Name: string = null;
    public Order: number = null;
}

我有一个 Angular 服务,可以调用后端来获取类别列表。一些组件具有创建新类别的功能。 在本例中,我希望初始列表中的所有订阅者都能更新为新类别。

export class CategoryService {
  constructor(private httpClient: HttpClient) {

  }

  public getCategories(): Observable<Category[]> {
    return this.httpClient.get<Category[]>('/api/CategoryAdmin/GetCategories');
  }

  public addCategory(newCategory: Category) {
    this.httpClient.post('/api/CategoryAdmin/AddCategory', newCategory).subscribe((result: Category) => {
      // what to do here?
    }, error => console.error(error));
  }

}

在上面的示例中,我看不出如何使 getCategories() 的初始订阅者收到已添加的新类别。我认为我需要将类别数组存储在 CategoryService 中,然后让每个订阅者订阅它。然而,我很难理解如何正确地做到这一点。我研究了一些主题,我认为这可能是实现这一目标的方法,但我再次忘记了实现它的方法。

有人愿意提供一个例子或为我指出正确的方向吗?


更新:根据下面的答案,我最终将代码更新为以下内容。我粘贴了整个内容,因为我认为这可以帮助人们更好地理解。

export class CategoryService {
  constructor(private httpClient: HttpClient) {

  }
  private _categories = new BehaviorSubject<CommandCategory[]>([]);
  private categories: CommandCategory[] = [];
  private loading: boolean = false;

  public get(): Observable<CommandCategory[]> {
    this.load();
    return this._categories.asObservable();
  }

  public load() {
    if (this.categories.length === 0 && !this.loading) {
      this.loading = true;
      this.httpClient.get<CommandCategory[]>('/api/CategoryAdmin/GetCategories').subscribe((data: CommandCategory[]) => {
          this.loading = false;
          this.categories = data;
          this._categories.next(this.categories);
        },
        error => {
          this.loading = false;
          console.log('Could not load categories.');
        });
    }
  }


  public save(categories: CommandCategory[]) {
    this.httpClient.post('/api/CategoryAdmin/SaveCategories', categories).subscribe(() => {
      for (var i = 0; i < categories.length; i++) {
        if (categories[i].IsDeleted)
          categories.splice(i, 1);
      }
      this.categories = categories;
      this._categories.next(this.categories);
    }, error => console.log('Could not save categories.'));
  }


  public add(category: CommandCategory) {
    this.httpClient.post('/api/CategoryAdmin/AddCategory', category).subscribe((result: CommandCategory) => {
      this.categories.push(result);
      this._categories.next(this.categories);
    }, error => console.error(error));
  }

}

最佳答案

您的两种方法都在不同的位置处理 API 的响应:

  • getCategories() 只是将检索到的类别列表传递给请求它们的组件/服务。
  • addCategory() 在实际的 CategoryService 中订阅

因此,您正在两个不同的地方处理数据存储:

您可以保存服务中的类别列表,并且组件使用它(因此您的 addCategory() 方法可以将新创建​​的类别推送到现有列表中)

或者您按照 getCategories() 进行操作,并将新创建的类别返回给添加它的实体(假设它是保存完整类别列表的实体)。


编辑:根据您的评论,我快速完成了 Stackblitz并为您的问题提供可能的解决方案。它基本上通过异步管道订阅位于服务中的 SPOT。

关于Angular - 如何正确使用 Services、HttpClient 和 Observables 在我的应用程序中传递对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57709103/

相关文章:

visual-studio - Typescript 2.0 tsc.exe 代码 1 错误(升级后)

javascript - GOJS 链接渲染不正确,在用户移动节点时纠正

angular - 如何在 Webstorm 的 Angular 2 模板中删除背景颜色

javascript - http-client 在响应到达时调用函数

angular - 在恢复之前等待 RxJs.Subscriptions 完成

angular - 如何在 Firefox 中正确调试 Angular - 错误 : "[object Object]"

angular - 浏览器在使用 azure 应用服务托管的根 index.html 上保留令人困惑的 Angular 应用的缓存版本

javascript - UglifyJS - Mangle 函数但保留 Function.prototype.name

angular - 如何创建在验证后返回 Observable 的函数?

node.js - RxJS - 使用 zip 并行化导致 HTTP 请求无法正常工作的延迟 Observables - 您在需要流的地方提供了无效的对象