Marionette CompositeView 排序渲染

Marionette CompositeView Sort Rendering

我有一个 Marionette (2.4.1) CompositeView,当我对它进行排序时 re-renders 整个视图而不是子视图。 header 图标还原。我可以在渲染时修复它们,但有没有一种方法可以只渲染 childView?

diaryEntries = Backbone.Marionette.CompositeView.extend({
  template  : diaryEntries,
  className: 'diary-entries',
  collection: new Diary(),
  childViewContainer: 'tbody',
  reorderOnSort: true,

  events: {
    'click th[data-sort]': 'sort',
    'click .pagination a': 'paginate'
  },

  initialize: function() {
    this.itemsPerPage = 5;
    this.currentPage = 1;
    this.pages;
  },

  ...

  sort: function(e) {
    var $th, dir, sort, sorted;
    e.preventDefault();
    $th = $(e.currentTarget);
    sort = $th.data('sort');

    if (sort === this.collection.sortField) {
      this.collection.sortDirection *= -1;
    } else {
      this.collection.sortDirection = 1;
    }

    this.collection.sortField = sort;

    $('span.glyphicon').removeClass('active-sort');
    $th.siblings('th').find('span.glyphicon').removeClass('glyphicon-chevron-down glyphicon-chevron-up').addClass('glyphicon-sort');

    if (this.collection.sortDirection === 1) {
      $th.find('span.glyphicon').removeClass('glyphicon-chevron-down glyphicon-sort').addClass('glyphicon-chevron-up active-sort');
    } else {
      $th.find('span.glyphicon').removeClass('glyphicon-chevron-up glyphicon-sort').addClass('glyphicon-chevron-down active-sort');
    }

    this.collection.sort();
  },
...

});

嗯,看起来 Marionette 和你一样担心。我在文档中找不到这个,但它在源代码中很简单。如果你传递这个选项:

reorderOnSort: true

进入您的 Collection/Composite 视图,在 'sort' 事件中,Collection/View 不会重新呈现,只是它的子项。

请参阅 Marionette 来源中的这一行:https://github.com/marionettejs/backbone.marionette/blob/v2.4.1/src/collection-view.js#L166

更新 如果您要过滤子视图,运行 对您的集合进行排序将调用 Collection/Composite 视图上的 render。其逻辑是,如果您对子结果进行分页,则必须对原始的、未过滤的集合进行排序以正确显示分页结果。

尽管如此,我没有发现任何本质上对过滤集进行分页的错误。

幸运的是,很容易覆盖 sort 方法来呈现您的结果是否被过滤。在你Collection/Composite视图中包括这个方法:

reorder: function() {
   var children = this.children;
   var models = this._filteredSortedModels();

   // get the DOM nodes in the same order as the models
   var els = _.map(models, function(model) {
     return children.findByModel(model).el;
   });

   this.triggerMethod('before:reorder');
   this._appendReorderedChildren(els);
   this.triggerMethod('reorder');
   }
},