web-dev-qa-db-ja.com

Observable <Array <any >>から特定の要素を削除する方法

場所の配列の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)
  );    
}  

これを手伝ってくれませんか?

13
daslashi

オブザーバブルを "更新"することはできない(つまり、状態を保持しない)ため、この方法では実行できませんが、それを介してイベントに反応することができます。

あなたのユースケースでは、scan演算子を利用して、2つのストリームを1つのストリームにマージします。

  • 最初の読み込み用
  • もう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

20

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)
  );    
}  
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));
0
Tecayehuatl

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' });

誰かのお役に立てば幸いです。

0
user12163165