Использование CollectionView расширенного функционала
CollectionView предоставляет множество возможностей для сортировки, фильтрации и управления дочерними элементами.
Индекс документации
Дочерние элементы 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