5

Sto provando a entrare in programmazione reattiva. Uso le funzioni dell'array come map, filter e riduco tutto il tempo e amo che posso manipolare gli array senza creare lo stato.Creazione di un elenco filtrabile con RxJS

Come esercizio, sto cercando di creare un elenco filtrabile con RxJS senza introdurre variabili di stato. Alla fine dovrebbe funzionare simile a questo:

enter image description here enter image description here

vorrei sapere come eseguire questa operazione con ingenua JavaScript o AngularJS/ReactJS ma sto cercando di fare questo con nulla, ma RxJS e senza creare variabili di stato:

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() {}); 

Ora come faccio ad ottenere il valore di ricerca nella mia funzione di filtro sul osservabile che ho creato dalla mia lista?

Grazie mille per il vostro aiuto!

risposta

5

Avrai bisogno di avvolgere il from(list) in quanto sarà necessario riavviare nuovamente l'elenco osservabile ogni volta che viene modificato il filtro. Dal momento che potrebbe accadere molto, probabilmente vorrete anche evitare il filtraggio quando il filtro è troppo corto, o se c'è un altro tratto di chiave entro un breve intervallo di tempo.

//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*/}); 

questo è tutto adattato da uno degli esempi standard, per RxJS here

1

È possibile creare un nuovo flusso, che prende l'elenco di persone e il flusso di chiavi, unirli e scansioni per filtrare quest'ultimo.

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))); 

In questo modo si avrà: lista

-L ------------------ persone

------ k ----- k - k ---- keyups flusso

-L ---- ----- k k - k ---- flusso fusa

Quindi è possibile eseguire la scansione . Come docs dice:

Rx.Observable.prototype.scan (accumulatore, [seme])

Applica una funzione accumulatore a una sequenza osservabile e restituisce ogni risultato intermedio .

Ciò significa che sarà possibile filtrare l'elenco, memorizzando il nuovo elenco sull'accumulatore.

Una volta iscritto, i dati saranno la nuova lista.

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

Speranza che aiuta/bastasse

chiaro
Problemi correlati