使用来自另一个observable的值过滤可观察对象

Ion*_*tan 30 reactive-extensions-js rxjs

我有两个可观察量:

  1. 表示复选框输入列表的observable.
  2. 表示来自服务器的事件流的可观察对象.

我想使用第一个值中的值来过滤第二个observable.

从服务器接收的值包括tag属性,该属性对应于复选框列表中的值.上述两者的组合产生的可观察性只会产生服务器的值,该服务器的tag属性包含在勾选复选框的集合中.

Dor*_*rus 33

你可以用withLatestFrom. 在此输入图像描述.

source.withLatestFrom(checkboxes, (data, checkbox) => ({data, checkbox}))
  .filter(({data, checkbox}) => ...)
Run Code Online (Sandbox Code Playgroud)

这里checkboxes是一个表示复选框输入列表的observable.source是一个可观察的,表示来自服务器的事件流.在过滤功能中,您可以检查数据与复选框设置相比是否有效,并让它通过.

请注意,checkboxes在流可以发出任何内容之前,重要的是发出至少1个值.

PS.关于其他答案,即使源是冷的,该解决方案仍然有效.


Gaj*_*jus 6

为了使用流B的值过滤流A,您需要观察流B并使用最新值来过滤流A.

使用switch()从A观察到的变换乙可观察到可观察到的产值.

checkedInputValuesSource
    .map(function (options) {
        return dataSource
            .filter(function (value) {
                return options.indexOf(value) !== -1;
            });
    })
    .switch()
    .subscribe(function (x) {
        console.log('out: ' + x);
    });
Run Code Online (Sandbox Code Playgroud)

使用switch()假设dataSource是一个热的可观察.

interval()用于生成虚拟数据的示例:

var input,
    checkedInputValuesSource,
    dataSource;

input = document.querySelectorAll('input');

// Generate source describing the current filter.
checkedInputValuesSource = Rx.Observable
    .fromEvent(input, 'change')
    .map(function () {
        var inputs = document.querySelectorAll('input'),
            checkedInputValues = [];
        
        [].forEach.call(inputs, function (e) {
            if (e.checked) {
                checkedInputValues.push(e.value);
            }
        });
        
        return checkedInputValues;
    })
    .startWith([]);

// Generate random data source (hot).
dataSource = Rx.Observable
    .interval(500)
    .map(function () {
        var options = ['a', 'b', 'c'];
    
        return options[Math.floor(Math.floor(Math.random() * options.length))];
    })
    .do(function (x) {
        console.log('in: ' + x);
    })
    .share();

checkedInputValuesSource
    .map(function (options) {
        return dataSource
            .filter(function (value) {
                return options.indexOf(value) !== -1;
            });
    })
    .switch()
    .subscribe(function (x) {
        console.log('out: ' + x);
    });
Run Code Online (Sandbox Code Playgroud)
<script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script>

<input type='checkbox' value='a'>
<input type='checkbox' value='b'>
<input type='checkbox' value='c'>
Run Code Online (Sandbox Code Playgroud)

此示例将生成类似于的输出:

in: c
in: a
out: a
in: b
in: c
out: a
in: b
in: a
Run Code Online (Sandbox Code Playgroud)

其中in反映了所有生成的输入和b通过过滤器的数据.通过选中反映值"a","b"和"c"的复选框输入来调整过滤器.

  • 可能.我正在浏览每个rxjs的问题/答案,并尽我所能做出贡献.您的答案链接到外部资源,需要运行其他依赖项.我在沙盒环境中写下了一个解决方案. (2认同)
  • 请注意,即使源是冷的,您也可以使此工作正常。使用 [`publish(...)`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publish.md)。像这样:`dataSource .publish(dsrc =&gt;checkedInputValuesSource.switchMap((options) =&gt; dsrc.filter((value) =&gt; options.indexOf(value) !== -1) ) )` (2认同)