Search code examples
javascriptbackbone.jsmarionette

Backbone (Marionette as well) trying to display a new record at the start of a collection, without re - rendering the whole collection


I'm trying to render an item at the start of a collection (imagine if you were posting a new record on facebook)

When I come to add(response, {at: 0}); into the collection, the record is correctly inserted at 0 into the collection, but is rendered at the bottom of the list of items. I'm confused as I had this working before, but I think what I was doing in a hacky style, was just reset and re-rendering the collection.

I'm wondering what the tidy way to handle this, and where should I bind the logic.

Is it on the add method of the collection? Currently this is empty (but I am using Marionette) and I feel that this overrides the default rendering of backbone. How do I take control of it again, so I can correctly get my new item to be added to the list, without destroying it all and re-creating it.


Solution

  • In Marionette, the default way to add a new item to a collection in the views, is to use jQuery's append method. The CollectionView type has a method called appendHtml which is used to do the actual appending. (see http://derickbailey.github.com/backbone.marionette/docs/backbone.marionette.html#section-24 )

    You can easily override this method in your specific collection view, though, and have the new model appended wherever it needs to go.

    In your case, if you are always wanting to prepend the new model to the top of the list, it's very trivial to change your collection view to do this:

    Backbone.Marionette.CollectionView.extend({
      appendHtml: function(cv, iv){
        cv.$el.prepend(iv.el);
      }
    });
    

    Note that cv is the collection view instance and iv is the item view instance for the model in the collection.

    If you need to do more complicated things like find an exact position in the existing collection of HTML nodes, you can do that within the appendHtml function as well. Of course this gets more complicated than just doing a prepend instead of an append, but it's still possible.

    Hope that helps.