Как удалить определенный элемент из Observable <Array<any> >
Существует Наблюдение за множеством мест:
places: Observable<Array<any>>;
В шаблоне он используется с асинхронной трубой:
<tr *ngFor="let place of places | async">
...
</tr>
После некоторых действий пользователя мне нужно удалить место с определенным идентификатором из этого массива. В моем коде есть что-то подобное, но это не работает:
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)
);
}
ты можешь помочь мне с этим?
Ответы
Ответ 1
Вы не можете сделать это так, потому что вы не можете "обновить" наблюдаемое (т.е. Не сохранять состояния), но вы можете реагировать на событие через него.
Для вашего случая использования я бы использовал оператора 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.
Ответ 2
Функция фильтра неизменна и не изменит исходный массив.
Я бы изменил функцию 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)
);
}