私はrxjsに少し慣れていないので、この問題に頭を悩ませることはできません。
私には2つのストリームがあります:
着信オブジェクトストリームから、オブジェクトのリストのストリームを作成します(スキャン演算子を使用)
incoming: ----a--------b-------c----------d----------------\>
list: -------[a]----[a,b]----[a,b,c]----[a,b,c,d]---------\>
リストオブジェクトが選択されたら(n)、新しいストリームを開始します
incoming: ----a--------b-------c----------d--------------------e-------->
list: -------[a]----[a,b]----[a,b,c]----[a,b,c,d]--------->
selected object: ---------------------------------c------->
new stream of list: ------[c,d]-----[c,d,e]--->
オブジェクトが選択されたときにリストストリームの最後の値を取得できません、、、理解を深めるために大理石の図を作成しました、
selectedObject$ = new BehaviorSubject(0);
incomingObjects$ = new Subject();
list$ = incomingObjects$.pipe(
scan((acc, val) => {
acc.push(val);
return acc;
}, [])
)
newList$ = selectedObject$.pipe(
withLastFrom(list$),
switchMap(([index,list])=> incomingObjects$.pipe(
scan((acc, val) => {
acc.push(val);
return acc;
}, list.slice(index))
))
)
スキャン演算子と一緒に使用する一般的なパターンは、現在の値を更新操作で使用できるように、スキャンする値の代わりにレデューサー関数を渡すことです。この場合、2つのオブザーバブルをマージ演算子でリンクし、それらの値を適切な関数にマップできます。リストに追加するか、選択後にリストをスライスします。
// these are just timers for demonstration, any observable should be fine.
const incoming$ = timer(1000, 1000).pipe(map(x => String.fromCharCode(x + 65)), take(10));
const selected$ = timer(3000, 3000).pipe(map(x => String.fromCharCode(x * 2 + 66)), take(2));
merge(
incoming$.pipe(map(x => (s) => [...s, x])), // append to list
selected$.pipe(map(x => (s) => { // slice list starting from selection
const index = s.indexOf(x);
return (index !== -1) ? s.slice(index) : s;
}))
).pipe(
scan((list, reducer) => reducer(list), []) // run reducer
).subscribe(x => console.log(x)); // display list state as demonstration.
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加