Понимание коллекции представления и фильтрации / сброса представления Backbone.js (из Router, Event и т. Д.)

Я все еще чувствую себя комфортно с Backbone.js, и есть много раз, когда я действительно думаю, что получаю это - тогда что-то настолько тривиальное всплывает, раскачивает мой мир и заставляет меня переосмыслить, если я вообще его получу. Это один из таких моментов - любая помощь будет оценена заранее.

У меня есть вид. Он имеет коллекцию (представление отображает список сессий в течение дня один час каждый тип вещи). Первоначально, когда представление создается впервые, я отображаю всю коллекцию сеансов. Все в порядке. В верхней части просмотра у меня есть 4 ссылки для каждого дня недели (во время нашего мероприятия) - 10, 11, 12, 13. Я хочу, чтобы пользователь мог кликать на день и фильтровать список сессий для этого конкретного дня (как я уже сказал, довольно тривиально).

Пока у меня это работает так:

  1. Коллекция 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;
        });        
    }
    
  2. Представление создается и инициализируется с полной коллекцией сеансов.

    new UGM.SessionsCollectionView({ collection: UGM.data.sessionsData });
    
  3. В моей коллекции 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 (из метода модели). Снова пока все хорошо.

  1. В моем контроллере (маршрутизаторе) у меня есть следующее (и это запутанная часть):

    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);
},
Другие вопросы по тегам