有一个地方数组的Observable:
places: Observable<Array<any>>;
在模板中,它与异步管道一起使用:
<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)
);
}
你能帮我解决这个问题吗?
答案 0 :(得分:20)
你不能这样做,因为你不能“更新”一个可观察的(即它不会保持状态),但你可以通过它对一个事件作出反应。
对于您的用例,我将利用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。
答案 1 :(得分:1)
过滤器功能是不可变的,不会改变原始数组。
我会将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)
);
}
答案 2 :(得分:1)
您可以利用 filter 运算符:
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));
答案 3 :(得分:1)
RxJS版本6
将接受的答案与 RxJS 6 和typescript
一起使用会引发错误,因为observables
具有不同的类型。您最好使用combineLatest
,也可以使用zip
,但这将不起作用!你只是问为什么?答案是here:)
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' });
我希望它能对某人有所帮助。