場所の配列の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)
);
}
これを手伝ってくれませんか?
オブザーバブルを "更新"することはできない(つまり、状態を保持しない)ため、この方法では実行できませんが、それを介してイベントに反応することができます。
あなたのユースケースでは、scan
演算子を利用して、2つのストリームを1つのストリームにマージします。
ここにサンプルがあります:
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 。
Filter関数は不変であり、元の配列を変更しません。
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)
);
}
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));
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' });
誰かのお役に立てば幸いです。