Spec-Zone.ru › Marionette.js 3

Использование CollectionView расширенного функционала

CollectionView предоставляет множество возможностей для сортировки, фильтрации и управления дочерними элементами.

Индекс документации

  • Дочерние элементы CollectionView

    • buildChildView CollectionView
    • addChildView CollectionView
    • CollectionView: Получение дочерних представлений
      • findByCid дочерних представлений CollectionView
      • findByModel дочерних представлений CollectionView
      • CollectionView дочерних представлений: findByModelCid
      • CollectionView дочерних представлений: findByCustom
      • CollectionView дочерних представлений: findByIndex
    • removeChildView CollectionView
    • Итераторы и функции коллекций дочерних представлений CollectionView
  • filter CollectionView

    • setFilter CollectionView
    • removeFilter CollectionView
  • sort CollectionView

    • viewComparator CollectionView
    • getViewComparator CollectionView
    • reorderOnSort CollectionView
    • reorder CollectionView
    • resortView CollectionView
  • Связывание ui

Дочерние элементы CollectionView

CollectionView может хранить и управлять своими дочерними представлениями. Это позволяет легко получать доступ к представлениям внутри коллекции представлений, итерировать их, находить их по заданному индексу, такому как модель представления или коллекция, и многое другое.

buildChildView CollectionView

buildChildView отвечает за получение класса ChildView и его инициализацию соответствующими данными. Этот метод принимает три параметра и возвращает экземпляр представления, который будет использоваться как дочернее представление.

buildChildView: function(child, ChildViewClass, childViewOptions){
  // build the final list of options for the childView class
  var options = _.extend({model: child}, childViewOptions);
  // create the child view instance
  var view = new ChildViewClass(options);
  // return it
  return view;
},

Переопределите этот метод, когда вам потребуется более сложная сборка, но используйте childView, если вам нужно определить какой класс представления следует инициализировать.

var Bb = require('backbone');
var Mn = require('backbone.marionette');

var MyCollectionView = Mn.CollectionView.extend({
  childView: function(child) {
    if (child.get('type') === 'list') {
      return MyListView;
    }

    return MyView;
  },
  buildChildView: function(child, ChildViewClass, childViewOptions) {
    var options = {};

    if (child.get('type') === 'list') {
      var childList = new Bb.Collection(child.get('list'));
      options = _.extend({collection: childList}, childViewOptions);
    } else {
      options = _.extend({model: child}, childViewOptions);
    }

    // create the child view instance
    var view = new ChildViewClass(options);
    // return it
    return view;
  }

});

addChildView CollectionView

Метод addChildView может использоваться для добавления представления, независимого от вашего Backbone.Collection. Обратите внимание, что добавленное представление будет подвержено фильтрации и упорядочению, и его может быть трудно управлять в сложных ситуациях. Используйте с осторожностью.

Этот метод принимает два параметра: экземпляр дочернего представления и индекс, в котором он должен быть размещен в дочерних элементах CollectionView.

var Mn = require('backbone.marionette');
var buttonView = new ButtonView();
var MyCollectionView = Mn.CollectionView.extend({
  onRender: function() {
    this.addChildView(buttonView, this.collection.length);
  }
});

var myCollectionView = new MyCollectionView();

myCollectionView.render();

CollectionView: Получение дочерних представлений

Вы можете получить представление по любому из индексов. Если метод findBy* не находит представление, он вернёт undefined.

CollectionView дочерних представлений: findByCid

Найти представление по его cid.

var bView = myCollectionView.children.findByCid(buttonView.cid);

CollectionView дочерних представлений: findByModel

Найти представление по модели.

var bView = myCollectionView.children.findByModel(buttonView.model);

CollectionView дочерних представлений: findByModelCid

Найти представление по cid модели.

var bView = myCollectionView.children.findByModelCid(buttonView.model.cid);

CollectionView дочерних представлений: findByCustom

Найти по пользовательскому ключу.

var bView = myCollectionView.children.findByCustom('custom_key');

CollectionView дочерних представлений: findByIndex

Найти по числовому индексу (нестабильно)

var bView = myCollectionView.children.findByIndex(0);

removeChildView CollectionView

Метод removeChildView полезен, если необходимо удалить представление из CollectionView без влияния на коллекцию представления. В большинстве случаев лучше использовать данные для определения того, что должно отображать CollectionView.

Этот метод принимает в качестве параметра экземпляр дочернего представления для удаления.

var Mn = require('backbone.marionette');

Mn.CollectionView.extend({
  onChildViewClose: function(childView, model) {
    // NOTE: we must wait for the server to confirm
    // the destroy PRIOR to removing it from the collection
    model.destroy({wait: true});

    // but go ahead and remove it visually
    this.removeChildView(childView);
  }
});

Итераторы и функции коллекций дочерних представлений CollectionView

Объект контейнера заимствует несколько функций из Underscore.js, чтобы предоставить итераторы и другие функции коллекций, включая:

  • each
  • map
  • reduce
  • find
  • filter
  • reject
  • every
  • some
  • contains
  • invoke
  • toArray
  • first
  • initial
  • rest
  • last
  • without
  • isEmpty
  • pluck

Эти методы можно вызывать непосредственно на контейнере для итерации и обработки представлений, хранящихся в контейнере.

var Bb = require('backbone');
var Mn = require('backbone.marionette');

var collectionView = new Mn.CollectionView({
  collection: new Bb.Collection()
});

collectionView.render();

// iterate over all of the views and process them
collectionView.children.each(function(childView) {
  // process the `childView` here
});

filter CollectionView

CollectionView позволяет настроить опцию filter, если вы хотите предотвратить отображение некоторых моделей базовой collection в виде дочерних представлений. Функция фильтрации принимает модель из коллекции и возвращает истинное значение, если дочерний элемент должен быть отображен, и ложное значение, если не должен.

var Bb = require('backbone');
var Mn = require('backbone.marionette');

var cv = new Mn.CollectionView({
  childView: SomeChildView,
  emptyView: SomeEmptyView,
  collection: new Bb.Collection([
    { value: 1 },
    { value: 2 },
    { value: 3 },
    { value: 4 }
  ]),

  // Only show views with even values
  filter: function (child, index, collection) {
    return child.get('value') % 2 === 0;
  }
});

// renders the views with values '2' and '4'
cv.render();

// change the filter
// renders the views with values '1' and '3'
cv.setFilter(function (child, index, collection) {
  return child.get('value') % 2 !== 0;
});

// renders all views
cv.removeFilter();

setFilter CollectionView

Метод setFilter изменяет атрибут фильтра CollectionView и отображает новое ChildViews эффективным способом, вместо повторного рендеринга всей структуры DOM. Передача { preventRender: true } в аргументе options предотвратит отображение представления.

var Mn = require('backbone.marionette');

var cv = new Mn.CollectionView({
  collection: someCollection
});

cv.render();

var newFilter = function(child, index, collection) {
  return child.get('value') % 2 === 0;
};

// Note: the setFilter is preventing the automatic re-render
cv.setFilter(newFilter, { preventRender: true });

//Render the new state of the ChildViews instead of the whole DOM.
cv.render();

removeFilter CollectionView

Эта функция фактически является псевдонимом setFilter(null, options). Она полезна для удаления фильтров. removeFilter также принимает preventRender в качестве опции.

var Mn = require('backbone.marionette');

var cv = new Mn.CollectionView({
  collection: someCollection
});

cv.render();

cv.setFilter(function(child, index, collection) {
  return child.get('value') % 2 === 0;
});

//Remove the current filter without rendering again.
cv.removeFilter({ preventRender: true });

sort CollectionView

По умолчанию CollectionView сохраняет порядок сортированной коллекции в DOM. Это поведение можно отключить, указав {sort: false} при инициализации. Флаг sort нельзя изменить после инициализации.

var Bb = require('backbone');
var Mn = require('backbone.marionette');

var myCollection = new Bb.Collection([
  { id: 1 },
  { id: 4 },
  { id: 3 },
  { id: 2 }
]);

myCollection.comparator = 'id';

var mySortedColView = new Mn.CollectionView({
  //...
  collection: myCollection
});

var myUnsortedColView = new Mn.CollectionView({
  //...
  collection: myCollection,
  sort: false
});

mySortedColView.render(); // 1 4 3 2
myUnsortedColView.render(); // 1 4 3 2

// mySortedColView auto-renders 1 2 3 4
// myUnsortedColView has no change
myCollection.sort();

viewComparator CollectionView

CollectionView позволяет настроить опцию viewComparator, если вы хотите, чтобы ваши дочерние элементы CollectionView отображались в другом порядке сортировки, чем использует базовая коллекция Backbone.

var Mn = require('backbone.marionette');

var cv = new Mn.CollectionView({
  collection: someCollection,
  viewComparator: 'otherFieldToSortOn'
});

viewComparator может принять любой допустимый Backbone.Collection формат компаратора — sortBy (передайте функцию, принимающую один аргумент), как компаратор (передайте функцию-компаратор, ожидающую два аргумента), или как строку, указывающую атрибут для сортировки.

getViewComparator CollectionView

Переопределите этот метод, чтобы определить, какой viewComparator использовать.

var Mn = require('backbone.marionette');

var MyCollectionView = Mn.CollectionView.extend({
  sortAsc: function(model) {
    return -model.get('order');
  },
  sortDesc: function(model) {
    return model.get('order');
  },
  getViewComparator: function() {
    // The collectionView's model
    if (this.model.get('sorted') === 'ASC') {
      return this.sortAsc;
    }

    return this.sortDesc;
  }
});

reorderOnSort CollectionView

Эта опция полезна, когда у вас есть проблемы с производительностью при сортировке CollectionView. Без этой опции ваше CollectionView будет полностью перерисовано, что может быть дорогостоящим, если у вас много элементов или ваши ChildView сложны. Если эта опция включена, при сортировке вашего Collection, перерисовки не будет, только узлы DOM будут переупорядочены. Это может быть проблемой, если ваши ChildView используют индекс своей коллекции в своём отображении. В этом случае вы не можете использовать эту опцию, так как вам нужно перерисовать каждое ChildView. Если вы объедините эту опцию с фильтром фильтра, который изменяет отображаемые представления, reorderOnSort будет пропущен для рендеринга новых дочерних элементов и удаления тех, которые отвергаются фильтром.

reorder CollectionView

Если reorderOnSort установлено в true, эта функция будет использоваться вместо перерисовки всех дочерних элементов. Её можно вызвать напрямую, чтобы предотвратить полную перерисовку коллекции. Это может быть полезно только если модели добавляются или удаляются скрытно или если sort было установлено в false для CollectionView.

resortView CollectionView

По умолчанию CollectionView сохраняет порядок своих collection в DOM. Однако в некоторых случаях для этого может потребоваться перерисовка представления, например, если вы измените компаратор коллекции. CollectionView перерисует своих дочерних элементов или reorder их в зависимости от reorderOnSort. Переопределите эту функцию, если вам нужна дальнейшая настройка.

var Mn = require('backbone.marionette');

var MyCollectionView = Mn.CollectionView.extend({
  resortView: function() {
    // provide custom logic for rendering after sorting the collection
  }
});

Связывание ui

По умолчанию, CollectionView не связывает объект ui. Поскольку у него нет собственного прямого template для управления, обычно это не проблема. Возможно, будут случаи, когда связывание ui будет полезно, когда вы хотите получить доступ к элементам внутри дочерних элементов CollectionView с getUI(). Если вам нужно связать ui самостоятельно, вы можете просто запустить bindUIElements для коллекции:

var Mn = require('backbone.marionette');

var MyCollectionView = Mn.CollectionView.extend({
  ...

  ui: {
    checkbox: 'input[type="checkbox"]'
  }
});

var collectionView = new MyCollectionView();

collectionView.bindUIElements();

console.log(collectionView.getUI('checkbox')); // Output all checkboxes.

© 2017 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v3.5.1/marionette.collectionviewadvanced.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API