有一个位置数组的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 6和typescript
将抛出错误,因为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' });