33

私は2つのオブザーバブルを持っています:

  1. チェックボックス入力のリストを表すオブザーバブル。
  2. サーバーからのイベントのストリームを表すオブザーバブル。

最初のオブザーバブルの値を使用して、2 番目のオブザーバブルをフィルター処理したいと思います。

サーバーから受信したtag値には、チェックボックス リストの値に対応するプロパティが含まれます。上記の 2 つの組み合わせから得られたオブザーバブルはtag、チェックボックスのセットにプロパティが含まれているサーバーからの値のみを生成します。

4

4 に答える 4

40

You can use withLatestFrom. enter image description here.

source.withLatestFrom(checkboxes, (data, checkbox) => ({data, checkbox}))
  .filter(({data, checkbox}) => ...)

Here, checkboxes is an observable representing a list of checkbox inputs. source is an observable representing a stream of events coming from the server. In the filter function you can check if the data is valid compared to the checkbox settings and let it trough.

Notice it is important checkboxes emits at least 1 value before the stream can emit anything.

Ps. In regard to other answers, this solution works even if the source is cold.

于 2016-08-24T22:03:17.220 に答える
6

ストリーム B の値を使用してストリーム A をフィルタリングするには、ストリーム B を観察し、最新の値を使用してストリーム A をフィルタリングする必要があります。

switch()B オブザーバブルを A オブザーバブルから値を生成するオブザーバブルに変換するために使用します。

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

を使用すると、それがホット オブザーバブル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);
    });
<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'>

この例では、次のような出力が生成されます。

in: c
in: a
out: a
in: b
in: c
out: a
in: b
in: a

Whereは、生成されたすべての入力とフィルターを通過したデータをin反映します。bフィルターは、値「a」、「b」、および「c」を反映するチェックボックスの入力をチェックすることによって調整されます。

于 2015-08-03T06:10:57.030 に答える
2

どうやら、私が必要としていたのはselectfilterとの組み合わせでしたswitchLatest。これを示す小さなテスト ケースを作成しました: https://gist.github.com/igstan/d5b8db7b43f49dd87382#file-observable-filter-observable-js-L36-L45

于 2013-07-19T12:33:50.767 に答える