Понимание коллекции представления и фильтрации / сброса представления Backbone.js (из Router, Event и т. Д.)
Я все еще чувствую себя комфортно с Backbone.js, и есть много раз, когда я действительно думаю, что получаю это - тогда что-то настолько тривиальное всплывает, раскачивает мой мир и заставляет меня переосмыслить, если я вообще его получу. Это один из таких моментов - любая помощь будет оценена заранее.
У меня есть вид. Он имеет коллекцию (представление отображает список сессий в течение дня один час каждый тип вещи). Первоначально, когда представление создается впервые, я отображаю всю коллекцию сеансов. Все в порядке. В верхней части просмотра у меня есть 4 ссылки для каждого дня недели (во время нашего мероприятия) - 10, 11, 12, 13. Я хочу, чтобы пользователь мог кликать на день и фильтровать список сессий для этого конкретного дня (как я уже сказал, довольно тривиально).
Пока у меня это работает так:
Коллекция Sessions (базовый класс) имеет метод filterByDay (day), который выполняет следующие действия:
filterByDay: function (day) { UGM.log('trying to filter by day of week: ' + day); return this.models.filter(function (s) { return moment.utc(s.get('StartTime')).format('DD') == day; }); }
Представление создается и инициализируется с полной коллекцией сеансов.
new UGM.SessionsCollectionView({ collection: UGM.data.sessionsData });
В моей коллекции View - у меня есть следующее:
events: { 'click a.dayFilter':'filterByDay' }, filterByDay: function (e) { e.preventDefault(); var day = (this.$(e.currentTarget).attr('rel')*1); this.render(this.collection.filterByDay(day)); UGM.router.navigate("/sessions/" + day); }
Итак, когда View загружается, все сессии отображаются нормально. Теги с классом dayFilter соответствующим образом инициируют событие, а filterByDay в представлении вызывает метод представления render(), передаваемый в отфильтрованную коллекцию NEW (из метода модели). Снова пока все хорошо.
В моем контроллере (маршрутизаторе) у меня есть следующее (и это запутанная часть):
showSessions: function (animate, level) { var section = new UGM.SessionsLayout({ collection: UGM.data.sessions }); this.displaySection(section, 'root', 'sessions', animate); }, showSessionsByDay: function(day, animate, level){ //** Should the next line really be that convoluted?!?! **// var section = new UGM.SessionsLayout({ collection: new UGM.SessionsCollection(UGM.data.sessions.filterByDay(day)) }); //** Why cant it just look like this: **// //var section = new UGM.SessionsLayout({ collection: UGM.data.sessions.filterByDay(day) }); this.displaySection(section, 'root', 'sessions/' + day, false); },
Обратите внимание на мой комментарий над рассматриваемой строкой. Все мои проблемы (по логике), похоже, связаны с моим непониманием того, как именно фильтр коллекций, фильтр collection.models, и тем фактом, что filter() всегда возвращает массив, а не коллекцию. (именно поэтому я объявляю новую базовую коллекцию внутри моего вызова фильтра из контроллера выше).
Извините, что это сбивает с толку или не имеет смысла, но, надеюсь, с таким количеством деталей кто-то может увидеть супер очевидную дыру в моей общей логике с тем, как я имею дело с коллекцией для начала.
Еще раз спасибо за любую помощь!!
1 ответ
Причина, по которой вы не можете просто сделать закомментированную строку, состоит в том, что filterByDay() возвращает массив моделей, а не коллекцию моделей. Это означает, что коллекция вашего представления не будет иметь функций, которые идут вместе с Backbone Collections. Если вы не хотите сбрасывать исходную коллекцию (что, похоже, у вас нет), вы делаете следующую лучшую вещь. Более читаемый способ сделать это (хотя это точно такой же код) может быть:
showSessionsByDay: function(day, animate, level){
var filteredCollection = new UGM.SessionsCollection(UGM.data.sessions.filterByDay(day));
var section = new UGM.SessionsLayout({ collection: filteredCollection });
this.displaySection(section, 'root', 'sessions/' + day, false);
},