【问题标题】:angular rxjs pipe remove element from array角度 rxjs 管道从数组中删除元素
【发布时间】:2018-10-30 09:20:06
【问题描述】:

我有一个带有删除功能的服务。删除函数将调用一个 api,它会返回 true 或 false。如果为真,我将在我的数组中查找索引,将其拼接并返回新数组。比如

private items = [];
onItemDeleted  = new Subject<any>();

  delete(id:number): Observable<any> {
    return this.http.delete('http://my.api.com/item/' + id)
      .pipe(
        switchMap(checkServerSuccessResponse),
        map(data => {
            const index1  = this.items.findIndex((element) => {
              return element.id === id;
            });
            if (index1 >= 0 ) {
              this.items.splice(index1,1);
            }
            this.onItemDeleted.next(this.items);
            return this.items;
          }
        ),
        catchError(returnFalse),
      );
  }

我有一个 switchmap 助手:

export function checkServerSuccessResponse(data: Response): Observable<any> {
    return (data && data['success'] === true) ? of(data) : throwError("server responded false");
}

虽然这可行,但我感觉地图部分可以重新格式化。我首先想到了过滤器(在 switchmap 之后)以排除具有我提供的 id 的元素,然后发出新数组,但后来我意识到,过滤器没有订阅 this.items 数组。

最好的方法是什么?

【问题讨论】:

  • 我不知道你的其他代码,例如this.items来自哪里,你为什么将更新的项目发布到onItemDeleted。但我可能会:a) 将this.items 传递给delete 方法也像delete(id, items) 因为在响应到达时,您不知道this.items 会发生什么; b) map 中的那个东西,移动到单独的函数,那将是 removeById(items, id); c) pipe 将变为 switchMap(checkServerSuccessResponse), map(removeById), tap(onItemDeleted.next), catchError(returnFalse)(电话缩写以适应此评论)。
  • 在 removeById 函数中移动删除的逻辑,这也是我想要的。但我不明白的是地图(removeById)。因为在管道的堆栈中,第一个参数是来自 api 调用(checkServerSuccessResponse 助手)的响应,而不是 this.items 数组

标签: javascript angular rxjs


【解决方案1】:

我不知道你的其他代码,例如this.items来自哪里,你为什么将更新的项目发布到onItemDeleted。但我可能会:a) 将this.items 传递给删除方法,也类似于delete(id, items),因为在响应到达时,您不知道this.items 会发生什么; b)地图中的那个东西,移动到单独的功能,那将是removeById(items, id); c) 简化pipe。像这样:

private items = [];
onItemDeleted  = new Subject<any>();

  removeById(fromItems, id) {
    const index1  = fromItems.findIndex((element) => {
      return element.id === id;
    });
    if (index1 >= 0 ) {
      fromItems.splice(index1,1);
    }
    return fromItems;
  }

  // who ever calls this, should provide copy of items also
  // then you will be kinda protected from concurrent
  // modification, when http response complete, but this.items
  // is completely different, from when http request started
  delete(fromItems, id:number): Observable<any> {
    return this.http.delete('http://my.api.com/item/' + id)
      .pipe(
        switchMap(checkServerSuccessResponse),
        map(data => this.removeById(fromItems, id)),
        tap(items => this.onItemDeleted.next(items)),
        catchError(returnFalse),
      );
  }

【讨论】:

  • 呃..现在很有意义..我坚持将函数直接映射到 removebyid 函数。
  • pipe 非常适合表达你想要做的事情,如果可能的话,用一个衬里变得更具可读性:)
  • 呵呵是的 .. 谢谢 .. 我被困在了我的脑海里 .. 现在可以工作了,即使是作为一个全局辅助函数 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 2019-11-06
  • 2022-01-13
  • 2016-03-08
  • 2017-09-13
相关资源
最近更新 更多