2016-02-03 3 views
1

У меня есть приложение стиля «email», в котором отображаются сообщения, сгруппированные по дате. Когда приложение загружается, мелкая коллекция сообщений извлекается и загружается в базовую коллекцию. Каждая модель в коллекции представляет собой список сообщений внутри группы. MessageGroup представляет группу сообщений, а MessagesView отображает группы сообщений.Marionette CollectionView не перерисовывается после collection.fetch

Все это хорошо работает до тех пор, пока сбор не будет получен снова, как после применения фильтра, отображаются только заголовки групп, а не сообщения внутри. Я пробовал запускать событие, которое может прослушивать MessagesView, а затем повторно отобразить его, но я получаю сообщение об ошибке: listening.obj.off is not a function.

var MessageModel = Backbone.Model.extend({}); 
var MessageCollection = Backbone.Collection.extend({ 
    model: MessageModel 
}); 

var GroupModel = Backbone.Model.extend({}); 
var GroupCollection = Backbone.Collection.extend({ 
    model: GroupModel, 
    url: '/messages/recipient', 
    parse: function (response) { 

     // Create a grouped JSON to render nested views with 
     var messageArray = []; 
     var groupedlist = _.groupBy(response.messages, function(model) { 
      return model.publishDate; 
     }); 

     _.forEach(groupedlist, function(n, key) { 
      var grouping = {}; 
      grouping.group = key; 
      grouping.list = n; 
      messageArray.push(grouping); 
     }); 

     return messageArray; 
    }, 
    fetchMessages: function() { 
     this.fetch({ 
      data: filtermodel.toJSON(), 
      success: function() { 

       var messagecollection = new MessageCollection(); 

       // Loop through each grouping and set sub-collections 
       groupcollection.each(function(group) { 
        var list = group.get('list'); 

        messagecollection.reset(list); 
        group.set('list', messagecollection); 
       }); 
      } 
     }); 
    } 
}); 

// Model to track applied filters 
var FilterModel = Backbone.Model.extend({ 
    defaults: { 
     folder: 0 
    } 
}); 

// ------------------------ VIEWS ------------- // 

// View for a single Message 
var MessageView = Backbone.Marionette.ItemView.extend({ 
    template: require('../../../templates/activities/message-item.ejs'), 
    events: { 'click li.item': 'getMessageDetail' }, 
    getMessageDetail: function(e){ 
     this.triggerMethod('showDetail', this.model); 
     //initMessageDetail(this.model); 
    } 

}); 

// Grouped container view for a list of Messages within a group 
var MessageGroup = Backbone.Marionette.CompositeView.extend({ 
    template: require('../../../templates/activities/message-list.ejs'), 
    className: "list-view-group-container", 
    childView: MessageView, 
    childViewContainer: "ul.viewcontainer", 
    initialize: function() { 
     this.collection = this.model.get('list'); 

    } 

}); 

// Top level view for all grouped messages 
var MessagesView = Backbone.Marionette.CollectionView.extend({ 
    childView: MessageGroup, 
    initialize: function() { 
     this.collection.on('change', this.log, this); 
    }, 
    log: function() { 
     console.log('triggered log'); 
    } 
}); 

// View for selected message detail 
var MessageDetailView = Backbone.Marionette.ItemView.extend({ 
    template: require('../../../templates/activities/message-detail.ejs'), 
    className: "message-content-wrapper" 
}); 

// View for filter selection bar 
var MessageFilterView = Backbone.Marionette.ItemView.extend({ 
    template: require('../../../templates/activities/message-filter-bar.ejs'), 
    events: { 
     'click #search-btn': function() { 
      filtermodel.set('search', $('#search-input').val()); 
      groupcollection.fetchMessages(); 
     } 
    } 
}); 


var filtermodel = new FilterModel(); 
var groupcollection = new GroupCollection(); 

// Fetch messages first run 
groupcollection.fetchMessages(); 


// LayoutView to display in center panel of application 
module.exports = ViewMessages = Marionette.LayoutView.extend({ 
    template: require('../../../templates/activities/viewmessages.ejs'), 
    className: 'content full-height', 
    regions: { 
     'messagelistregion': '#messageList', 
     'messagedetailregion': '.message-detail', 
     'messagefilterregion': '.filter-bar' 
    }, 
    childEvents: { 'showDetail': 'onMessageSelected' }, 
    onMessageSelected: function (childView, childViewModel) { 

     var that = this; 

     var detailModel = childViewModel.clone(); 
     var messageDetailView = new MessageDetailView({model:detailModel}); 
     that.messagedetailregion.show(messageDetailView); 
    }, 
    onShow: function(){ 

     var that = this; 
     var messagesview = new MessagesView({ 
      collection: groupcollection 
     }); 

     var messageFilterView = new MessageFilterView(); 
     that.messagelistregion.show(messagesview); 
     $("#messageList").ioslist(); 

     that.messagefilterregion.show(messageFilterView); 
     this.messagedetailregion.on('show', function() { 
      console.log('message detail region shown:' + that.messagedetailregion.currentView); 
     }) 
    } 
}); 

Я имею в виду его, потому что работа, которая делается для построения группировок сообщений внутри обратного вызова успеха не заканчивается до того, как событие сброса тревоги и вид обновляется. Как я могу получить MessagesView для обновления после последующих выборок?

UPDATE: я переехал логику после успеха группирования коллекции в своей иерархической структуре дерева/листа к пользовательскому событию (fetchSuccess) в CollectionView верхнего уровня (MessagesView):

var MessagesView = Backbone.Marionette.CollectionView.extend({ 
    childView: MessageGroup, 
    initialize: function() { 
     this.collection.on('fetch:success', this.fetchSuccess, this); 
    }, 
    fetchSuccess: function() { 
     var messagecollection = new MessageCollection(); 

     groupcollection.each(function(group) { 
      var list = group.get('list'); 

      messagecollection.reset(list); 
      group.set('list', messagecollection); 
     }); 
    } 
}); 

Он запускается при успешном обратном вызове извлечения. Я уверен, что это хороший способ визуализации коллекции, но я не могу показаться, чтобы обойти эту ошибку в марионеток:

**Uncaught TypeError: listening.obj.off is not a function** 

Кто-нибудь есть какие-либо идеи, почему это CollectionView не будет вновь сделать ??

ответ

1

я был в состоянии определить, что создание моделей в коллекции произошло после того, как событие сброса, но до того, как структура вложенных моделей была построена из:

success: function() { 

    var messagecollection = new MessageCollection(); 

    // Loop through each grouping and set sub-collections 
    groupcollection.each(function(group) { 
     var list = group.get('list'); 

     messagecollection.reset(list); 
     group.set('list', messagecollection); 
    }); 
}; 

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

groupcollection.fetch({ 
    reset: true, 
    data: filtermodel.toJSON(), 
    success: function() { 

     groupcollection.each(function(group) { 
      var list = group.get('list'); 

      var messagecollection = new MessageCollection(list); 
      group.set('list', messagecollection); 
     }); 

     filteredcollection.reset(groupcollection.toJSON()); 
    } 
}); 
Смежные вопросы