使用RxJS创建可过滤列表

时间:2015-05-29 13:00:31

标签: javascript functional-programming reactive-programming rxjs reactive-extensions-js

我试图进入反应式编程。我使用数组函数,如map,filter和减少所有的时间,并且喜欢我可以进行数组操作而不创建状态。

作为练习,我试图在不引入状态变量的情况下使用RxJS创建可过滤列表。最后它应该与此类似:

enter image description here enter image description here

我知道如何用朴素的JavaScript或AngularJS / ReactJS来实现这个目标,但我试图用RxJS做任何事情而不创建状态变量:

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

现在如何在我从列表中创建的observable中将搜索值输入到我的过滤器函数中?

非常感谢你的帮助!

4 个答案:

答案 0 :(得分:5)

您需要包装from(list),因为每次更改过滤器时都需要重新启动列表observable。由于这种情况可能会发生很多,因此您可能还希望在过滤器太短时防止过滤,或者在较短的时间范围内有另一个击键。

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

这全部改编自RxJS here

的标准示例之一

答案 1 :(得分:1)

您可以创建一个新流,它会获取人员和密钥组流的列表,合并它们并扫描以过滤后者。

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

这样你就有了:

-L ------------------人员名单

------ k ----- k - k ---- keyups stream

-L ---- k ----- k - k ----合并流

然后你可以扫描它。正如文档所说:

  

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

     

在可观察序列上应用累加器函数并返回每个函数   中间结果。

这意味着您将能够过滤列表,将新列表存储在累加器上。

订阅后,数据将成为新列表。

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

希望它有所帮助/足够清楚

答案 2 :(得分:0)

你可以看看我是怎么做到的: https://github.com/erykpiast/autocompleted-select/

它是端到端解决方案,通过抓取用户交互并将过滤后的列表呈现给DOM。

答案 3 :(得分:0)

您也可以查看WebRx's List-Projections

Live-Demo

披露:我是该框架的作者。