如何对rxjs中的现有流进行排序?

时间:2016-03-17 03:11:31

标签: javascript sorting rxjs

我是RxJs的新手。我有一个从ajax获取数据的响应流。另外,我有另一个按钮排序。我可以毫无问题地排序。我的问题是我是否正确地进行了排序和更新?我正在做的只是清空子节点并附加新结果。

(function($, _) {
  var fetchRepoButton = $('.fetch');
  var sortByButton = $('.sort-by');

  var fetchRepoClickStream = Rx.Observable.fromEvent(fetchRepoButton, 'click');

  var sortByClickStream = Rx.Observable.fromEvent(sortByButton, 'click');

  var requestStream = fetchRepoClickStream.map(function() {
    return '/api';
  });

  var responseStream = requestStream.flatMap(function (requestUrl) {
    return Rx.Observable.fromPromise($.getJSON(requestUrl));
  });

  responseStream.subscribe(function (es) {
    var repositories = $('.container');
    repositories.empty();
    var names = es.map(function (e) {
      return {name: e.name};
    }).forEach(function (e) {
      var rep = $('<div>');
      rep.html(e.name);
      repositories.append(rep);
    });

  });

  var sortByStream = sortByClickStream.combineLatest(responseStream, function (click, es) {
    return _.sortBy(es, function(e) {
      return e.count;
    }).reverse().map(function (e) {
      return {name: e.name, count: e.count};
    });
  });

  sortByStream.subscribe(function(es) {
    var repositories = $('.container');
    repositories.empty();
    var names = es.map(function (e) {
      return {name: e.name};
    }).forEach(function (e) {
      var rep = $('<div>');
      rep.html(e.name);
      repositories.append(e);
    });
  });


})($, _);

我现在正在玩这些代码。所以可能会有重复。

1 个答案:

答案 0 :(得分:1)

您的代码没有任何错误,并且您的RxJS使用情况看起来很好,尽管您的DOM使用情况并未尽可能优化。创建/删除所有这些DOM元素是一个相对昂贵的过程,因此理想情况下,您希望尽可能恢复元素。您的排序代码似乎已经成熟,可以在这方面进行优化。

对列表进行排序时,您知道每个DOM元素已经存在。我不是删除所有这些,而是​​以正确的顺序重新创建它们,而是使用detach()从页面中删除元素并将其返回,然后使用container.append(element)以正确的顺序添加它们

如果我正在实现它,我在最初创建元素时会执行rep.data('listCount', e.count)之类的操作,因此我们可以直接对jQuery元素进行排序,然后对列表进行排序:

sortByClickStream.subscribe(function() {
  var container = $('.container');

  // `.children()` returns raw DOM elements, so wrap each in jQuery
  _.map(container.children(), function(el) { return $(el); })
    .sortBy(function(item) { return item.data('listCount'); })
    .reverse()
    .forEach(function(item) {
      item.detach();
      container.append(item);
    });
});

可以使用响应流列表执行类似的操作,但需要做更多工作,因为您无法保证最新列表中的每个元素都已有元素。

总的来说,你所拥有的功能将会很好,对于中小型列表来说应该足够快。如果你的预期列表大小似乎变得缓慢,那么我将开始优化DOM代码。像Angular这样的框架具有专用于“DOM diffing”的整个库,以确定修改DOM以获得更新内容所需的最小数量的更改。如果您正在进行大量此类内容更新,我会考虑使用具有此内置功能的库/框架。