title: Marionette CollectionView not re-rendering after collection.fetch
body: <p>I have an 'email' style app that displays messages grouped by the date.  When the app loads, a shallow collection of messages are fetched and loaded into a backbone collection. Each model in the collection represents a list of messages within a grouping.  The <code>MessageGroup</code> represents a group of messages and the <code>MessagesView</code> displays the groups of messages. </p>
  
  <p>This all works well until the collection is fetched again like after a filter is applied, only the group headers are displayed, not the messages inside.  I've tried triggering an event that the <code>MessagesView</code> can listen for, then re-render itself but I get an error: <code>listening.obj.off is not a function</code>. </p>
  
  <pre><code>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);
          })
      }
  });
  </code></pre>
  
  <p>I'm thinking its because the work that is done to build out the groupings of messages inside the success callback doesn't finish before the reset event is triggered and the view is refreshed.  How can I get the <code>MessagesView</code> to update after subsequent fetches?</p>
  
  <p><strong>UPDATE:</strong> 
  I moved the post-success logic of grouping the collection into its hierarchical tree/leaf structure to a custom event (fetchSuccess) in the top level collectionview (<code>MessagesView</code>):</p>
  
  <pre><code>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);
          });
      }
  });
  </code></pre>
  
  <p>It is being triggered in the success callback of the fetch. I'm pretty sure this is a good way of rendering the collection, but I cant seem to get around the error in Marionette:</p>
  
  <pre><code>**Uncaught TypeError: listening.obj.off is not a function**
  </code></pre>
  
  <p>Anyone have any ideas why this collectionview will not re-render??</p>