Frage Filtern Sie ein Observable mithilfe von Werten aus einem anderen Observable


Ich habe zwei Observable:

  1. Ein Observable, das eine Liste von Checkbox-Eingaben darstellt.
  2. Ein Observable, der einen Stream von Ereignissen darstellt, die vom Server kommen.

Ich möchte das zweite Observable mit Werten aus dem ersten filtern.

Die vom Server empfangenen Werte umfassen a tag Eigenschaft, die den Werten in der Checkbox-Liste entspricht. Die Beobachtbarkeit, die sich aus der Kombination der beiden obigen ergibt, würde nur Werte von dem Server ergeben, dessen tag Eigenschaft ist in den markierten Kontrollkästchen enthalten.


18
2017-07-19 11:54


Ursprung


Antworten:


Sie können verwenden withLatestFrom. enter image description here.

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

Hier, checkboxes ist eine Observable, die eine Liste von Checkbox-Eingaben darstellt. source ist ein Observable, der einen Stream von Ereignissen darstellt, die vom Server kommen. In der Filterfunktion können Sie überprüfen, ob die Daten im Vergleich zu den Checkbox-Einstellungen gültig sind und lassen Sie sie durch.

Beachten Sie, dass es wichtig ist checkboxes gibt mindestens 1 Wert aus, bevor der Stream etwas ausstrahlen kann.

Ps. In Bezug auf andere Antworten funktioniert diese Lösung sogar, wenn die Quelle ist kalt.


22
2017-08-24 22:03



Um den Stream A mit den Werten von Stream B zu filtern, müssen Sie Stream B beobachten und die letzten Werte verwenden, um Stream A zu filtern.

Benutzen switch() das beobachtbare B in beobachtbare Werte umwandeln, die von A beobachtbar sind.

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

Verwenden switch() nimmt das an dataSource ist ein heiß beobachtbar.

Beispiel mit interval() Dummy-Daten erzeugen:

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'>

Dieses Beispiel erzeugt eine Ausgabe ähnlich der folgenden:

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

Woher in reflektiert alle generierten Eingaben und b die Daten, die den Filter passieren. Der Filter wird angepasst, indem die Checkbox-Eingaben aktiviert werden, die die Werte "a", "b" und "c" widerspiegeln.


5
2017-08-03 06:10



Anscheinend brauchte ich eine Kombination von select, filter und switchLatest. Ich habe einen kleinen Testfall geschrieben, der folgendes zeigt: https://gist.github.com/igstan/d5b8db7b43f49dd87382#file-observable-filter-observable-js-L36-L45


2
2017-07-19 12:33