如何从可观察<数组中删除特定元素<any>>



有一个位置数组的Observable:

places: Observable<Array<any>>;

与async管道一起使用的模板:

<tr *ngFor="let place of places | async">
  ...
</tr>

在一些用户操作之后,我需要从这个数组中删除具有特定id的地方。我的代码中有这样的东西,但它不起作用:

deletePlace(placeId: number): void {
  this.apiService.deletePlace(placeId)
  .subscribe(
    (res: any) => {
      this.places
        .flatMap((places) => places)
        .filter((place) => place.id != placeId);
    }, 
    (err: any) => console.log(err)
  );    
}  
你能帮我一下吗?

你不能这样做,因为你不能"更新"一个可观察对象(即它不保持状态),但你可以通过它对一个事件做出反应。

对于您的用例,我将利用scan操作符并将两个流合并为一个:

  • 初始加载
  • 用于删除事件。

示例:

let obs = this.http.get('/data').map(res => res.json());
this.deleteSubject = new Subject();
this.mergedObs = obs.merge(this.deleteSubject)
.startWith([])
.scan((acc, val) => {
  if (val.op && val.op==='delete') {
    var index = acc.findIndex((elt) => elt.id === val.id);
    acc.splice(index, 1);
    return acc;
  } else {
    return acc.concat(val);
  }
});

要触发元素删除,只需在主题上发送一个事件:

this.deleteSubject.next({op:'delete', id: '1'});

查看此plunkr: https://plnkr.co/edit/8bYoyDiwM8pM74BYe8SI?p=preview

您可以利用过滤器操作符:

this.places$
        .pipe(
            map(places => {
                // Here goes some condition, apply it to your use case, the condition only will return when condition matches
                return places.filter(place => place.placeId !== 0);
            }),
            map(response => (this.users$ = of(response)))
        )
        .subscribe(result => console.warn('Result: ', result));

过滤器函数是不可变的,不会改变原始数组。

我将把deletePlace函数改成这样:-

deletePlace(placeId: number):  void {
  this.apiService.deletePlace(placeId)
  .subscribe(
    (res: any) => {
      this.places = this.places.filter((place) => place.id != placeId);
    }, 
    (err: any) => console.log(err)
  );    
}  

RxJS版本6

使用RxJS 6typescript将抛出错误,因为observables持有不同的类型。你最好使用combineLatest,你也可以使用zip,但它不会工作!你刚问为什么了吗?答案在这里:)

combineLatest([
  this.items$,
  this.deleteItem$
]).pipe(
  takeUntil(this.onDestroy),
  tap(([items, deleteItem]) => {
    if (deleteItem && deleteItem.op === 'deleteItem') {
      var index = items.findIndex((item) => item.id === deleteItem.id);
      if (index >= 0) {
        items.splice(index, 1);
      }
      return items;
    }
    else {
      return items.concat(deleteItem);
    }
  })
).subscribe();

则可以发送事件…

this.deleteItem$.next({ op: 'deleteItem', id: '5e88fce485905976daa27b8b' });

最新更新