5

Ich versuche, in reaktive Programmierung zu bekommen. Ich benutze Array-Funktionen wie map, filter und reduziere die ganze Zeit und liebe, dass ich Array-Manipulation machen kann, ohne einen Zustand zu erzeugen.Erstellen einer filterbaren Liste mit RxJS

Als Übung versuche ich eine filterbare Liste mit RxJS ohne Einführung von Zustandsvariablen zu erstellen. Am Ende soll es ähnlich wie diese Arbeit:

enter image description here enter image description here

Ich würde wissen, wie das mit dem naiven JavaScript zu erreichen oder AngularJS/ReactJS aber ich versuche, dies aber RxJS mit nichts zu tun und ohne die Schaffung Zustandsvariablen:

var list = [ 
    'John', 
    'Marie', 
    'Max', 
    'Eduard', 
    'Collin' 
]; 

Rx.Observable.fromEvent(document.querySelector('#filter'), 'keyup') 
    .map(function(e) { return e.target.value; }); 

// i need to get the search value in here somehow: 
Rx.Observable.from(list).filter(function() {}); 

Nun, wie kann ich den Suchwert in meine Filterfunktion auf den beobachtbaren bekommen, dass ich von meiner Liste erstellt?

Vielen Dank für Ihre Hilfe!

Antwort

5

Sie müssen die from(list) umbrechen, da die Liste jedes Mal neu gestartet werden muss, wenn der Filter geändert wird. Da dies sehr häufig passieren kann, möchten Sie wahrscheinlich auch verhindern, dass der Filter gefiltert wird, wenn der Filter zu kurz ist oder wenn innerhalb eines kurzen Zeitrahmens ein weiterer Tastenanschlag erfolgt.

//This is a cold observable we'll go ahead and make this here 
var reactiveList = Rx.Observable.from(list); 

//This will actually perform our filtering 
function filterList(filterValue) { 
    return reactiveList.filter(function(e) { 
    return /*do filtering with filterValue*/; 
    }).toArray(); 
} 


var source = Rx.Observable.fromEvent(document.querySelector('#filter'), 'keyup') 
    .map(function(e) { return e.target.value;}) 

    //The next two operators are primarily to stop us from filtering before 
    //the user is done typing or if the input is too small 
    .filter(function(value) { return value.length > 2; }) 
    .debounce(750 /*ms*/) 

    //Cancel inflight operations if a new item comes in. 
    //Then flatten everything into one sequence 
    .flatMapLatest(filterList); 

//Nothing will happen until you've subscribed 
source.subscribe(function() {/*Do something with that list*/}); 

Das alles von einem der Standardbeispiele für RxJS here

1

Sie können einen neuen Stream erstellen, der die Personenliste und den Keypads-Stream aufnimmt, sie zusammenführt und scannt, um Letzteres zu filtern.

const keyup$ = Rx.Observable.fromEvent(_input, 'keyup') 
    .map(ev => ev.target.value) 
    .debounce(500); 

const people$ = Rx.Observable.of(people) 
    .merge(keyup$) 
    .scan((list, value) => people.filter(item => item.includes(value))); 

diese Weise werden Sie haben:

-L ------------------ Menschen

Liste

------ k ----- k - k ---- keyups Strom

-L ---- k ----- k - k ---- fusionierte Strom

Dann können Sie es scannen . Wie docs sagt:

Rx.Observable.prototype.scan (Akkumulator, [seed])

eine Akkumulatorfunktion auf einem beobachtbaren Ablauf gilt und gibt jedes Zwischenergebnis.

Das bedeutet, Sie können die Liste filtern und die neue Liste auf dem Akku speichern.

Sobald Sie abonnieren, werden die Daten die neue Liste sein.

people$.subscribe(data => console.log(data)); //this will print your filtered list on console 

Hoffe, es hilft/klar genug

war