【问题标题】:How to update new properties on many objects returned by an Observable?如何更新 Observable 返回的许多对象的新属性?
【发布时间】:2020-09-02 22:59:31
【问题描述】:

我正在从我的 API 中获取大量对象(类别)。一次从 API 返回 50 到 200 个类别。 我正在创建一个源 observable,它将所有类别过滤为 2 个子类别,并将它们作为单个对象下的单独属性返回。

public allCategories$: Observable<any> = this.categoryService.getAllCategories()
  .pipe(
    map((allCategories: CategoryModel[]) => {
      const red = allCategories.filter((cat) => cat.color === 'red');
      const blue = allCategories.filter((cat) => cat.color === 'blue');
      const allCats = { red, blue };
      return allCats;
    }),
    publishReplay(1),
    refCount()
  )

然后我使用异步管道以角度订阅,然后使用单独的 ngFors 循环遍历每个红色/蓝色流。

在我的标记中,每个类别都有一个与之关联的复选框。 然后用户可以搜索所有类别并将相应的复选框选中为真,然后用户可以提交这些类别以使用参数进行路由以在其他地方处理。

我面临的问题是:

  • 这些用户操作在同一页面的两个位置可用:一个模式,一个预先输入。
  • 两个组件都需要能够在不更新数据库的情况下读取和写入源 observable,并且基本上暂时保持这两个组件的状态
  • 我无法理解如何在订阅开始后更新被下推的对象,因为每当更新一个复选框时,对于主题的下一个 50-200 多个对象似乎不太高效

我研究了一些更复杂的 rxjs 模式,但对于我正在开发的已经臃肿的 Angular 应用程序来说,它们似乎有点矫枉过正。 对于这样的事情,什么是好的精简架构?

【问题讨论】:

  • 当一个组件“写入”到源时,是否也必须在另一个组件中看到更改?或者仅仅标记发生了变化就足够了?
  • 在路线改变之前,两个组件都会看到变化@AndreiGătej

标签: angular typescript rxjs angular-observable


【解决方案1】:

对于您的问题,您似乎不需要rxjs,因为所有数据都可以存储在一个组件中,尽管它在如何选择数据方面使用了多种方法。

您可以简单地添加一个属性来将所选类别的 id 存储到组件中,它不应与类别数据流和 rxjs 绑定。

class MyComponent {
  public allCategories$: Observable<any> = this.categoryService.getAllCategories().pipe(
    map((allCategories: CategoryModel[]) => {
      const red = allCategories.filter((cat) => cat.color === 'red');
      const blue = allCategories.filter((cat) => cat.color === 'blue');
      const allCats = { red, blue };
      return allCats;
    }),
    publishReplay(1),
    refCount()
  );

  // here we will store selected ids
  public selectedCategories: Array<string> = []; // array of ids.

  // our callback to handle selection
  public toggleCategory(id: string) {
    if (this.selectedCategories.indexOf(id) === -1) {
      this.selectedCategories = [
        ...this.selectedCategories,
        id,
      ];
    } else {
      this.selectedCategories = this.selectedCategories.filter(v => v !== id);
    }
  }

  // our callback how to save selection
  public submit() {
    this.categoryService.send(this.selectedCategories); // doing something.
  }
}

然后在模板中

<ng-container *ngIf="allCategories$ | async as categories">
  <div *ngFor="let category of categories.red">
    <!-- to manage selection we don't need rxjs -->
    <input type="checkbox" (click)="toggleCategory(category.id)" [checked]="selectedCategories.indexOf(category.id) !== -1"> {{ category.name }}<br>
  </div>

  <div *ngFor="let category of categories.blue">
    <input type="checkbox" (click)="toggleCategory(category.id)" [checked]="selectedCategories.indexOf(category.id) !== -1"> {{ category.name }}<br>
  </div>

  <button (click)="submit()">Save chosen categories</button>
</ng-container>

如果您想在多个组件之间共享选择,那么您可以创建单独的服务端点来如何切换选择以及如何获取它,在这种情况下使用combineLatest([this.allCategories$, this.selectedIds$]) 可能会很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2020-04-06
    • 2016-08-08
    相关资源
    最近更新 更多