我有一个场景我想帮助弄清楚如何在rxjs中实现它。
来源可观测量:
single
:使用id字段发出单个值many
:发出与single
流要求:
概述:流的最终结果是一个值数组,表示many
发出的最新值,由single
上一次发出后many
发出的值覆盖。< / p>
many
至少发出一次single
发出的值会累积并覆盖many
many
发出累积的single
值时会被清除实际情景:
我有一个可过滤的数据表组件,它有子组件,代表每列的每个过滤器。与每列(many
)对应的过滤器设置列表可以从其父列表下推到组件中。子过滤器组件可以为自己发出过滤器更改(single
)。父组件的设置优先于子过滤器组件。
我尝试过什么
console.clear();
const many = Rx.Observable.create(o => {
setTimeout(() => {
o.next([
{ id: 1, value: 'a' },
{ id: 2, value: 'b' },
{ id: 3, value: 'c' }
]);
}, 1000);
setTimeout(() => {
o.next([
{ id: 1, value: 'x' },
{ id: 2, value: 'y' },
{ id: 3, value: 'z' }
]);
}, 4000);
});
const single = Rx.Observable.create(o => {
o.next({ id: 1, value: 'd' });
setTimeout(() => { o.next({ id: 2, value: 'e' }); }, 2000);
setTimeout(() => { o.next({ id: 3, value: 'f' }); }, 3000);
setTimeout(() => { o.next({ id: 1, value: 'g' }); }, 5000);
});
single
.scan((acc, x) => {
return [...acc.filter(y => y.id !== x.id), x];
}, [])
.startWith([])
.combineLatest(many)
.map(x => {
const s = x[0];
const m = x[1];
return [...m.filter(y => !s.some(z => z.id === y.id)), s];
})
.subscribe(x => { console.log(JSON.stringify(x)); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.5/Rx.min.js"></script>
当single
发出时,此代码不会重置累积的many
值。
问题
如何在rxjs中实现上述场景?
我找到了一个解决方案(发布在下面),但我会接受更好的实施。谢谢!
答案 0 :(得分:0)
Blaaah ......发布后我很快意识到我做错了什么。我只需要颠倒顺序。这是我的解决方案,但我愿意接受更好的选择。
const many = new Rx.Subject();
const single = new Rx.Subject();
// create the stream
const stream = many
.switchMap(m => {
return single
.scan((acc, x) => {
return [...acc.filter(y => y.id !== x.id), x];
}, [])
.startWith([])
.map(s => {
return [...m.filter(y => !s.some(z => z.id === y.id)), ...s];
});
})
.subscribe(x => { console.log(JSON.stringify(x)); });
// send the data
single.next({ id: 1, value: 'd' });
setTimeout(() => {
many.next([
{ id: 1, value: 'a' },
{ id: 2, value: 'b' },
{ id: 3, value: 'c' }
]);
}, 1000);
setTimeout(() => { single.next({ id: 2, value: 'e' }); }, 2000);
setTimeout(() => { single.next({ id: 3, value: 'f' }); }, 3000);
setTimeout(() => {
many.next([
{ id: 1, value: 'x' },
{ id: 2, value: 'y' },
{ id: 3, value: 'z' }
]);
}, 4000);
setTimeout(() => { single.next({ id: 1, value: 'g' }); }, 5000);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.5/Rx.min.js"></script>
&#13;