5

我正在尝试进入反应式编程。我一直使用 map、filter 和 reduce 之类的数组函数,并且喜欢我可以在不创建状态的情况下进行数组操作。

作为一个练习,我正在尝试使用 RxJS 创建一个可过滤的列表,而不引入状态变量。最后它应该类似于这样工作:

在此处输入图像描述 在此处输入图像描述

我会知道如何使用幼稚的 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

4 回答 4

5

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

//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 的标准示例之一

于 2015-05-29T15:50:00.580 回答
1

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

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 流

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

然后就可以扫描了。正如文档所说:

Rx.Observable.prototype.scan(累加器,[种子])

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

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

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

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

希望它有帮助/足够清楚

于 2016-04-30T16:41:53.020 回答
0

您可以在这里查看我是如何做到的: https ://github.com/erykpiast/autocompleted-select/

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

于 2015-05-29T19:10:18.393 回答
0

你也可以看看WebRx 的 List-Projections

现场演示

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

于 2015-05-31T07:56:52.367 回答