Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Marionette to group items in a collection view

I'm building an application using backbone and marionette.js. I'm planning on using a collection view to present some items and then allow them to be filtered, sorted and grouped.

I was wondering if there are any good design ideas for actually appending the html in a grouped fashion. I have a few ideas but I was wondering if someone might have input on which would be better design.

My first idea is to change the appendHtml method on the collection view, and if grouping is enabled, I can have the appendHtml function either find or create the child group's bin and place the child view in it.

appendHtml: function(collectionView, itemView, index){
  var $container = this.getItemViewContainer(collectionView);

  // get group from model
  var groupName = itemView.model.get("group");

  // try to find group in child container
  var groupContainer  = $container.find("." + groupName);

  if(groupContainer.length === 0){
    // create group container
    var groupContainer = $('<div class="' + groupName + '">')
    $container.append(groupContainer);
  }

  // Append the childview to the group
  groupContainer.append(itemView);
}

My second idea is to break apart the collection into groups first and then maybe render multiple views... This one seems like it might be more work, but might also be a bit better as far as the code structure is concerned.

Any suggestions or thought eliciting comments would be great!

Thanks

like image 346
MattyP Avatar asked Feb 12 '13 18:02

MattyP


2 Answers

Maybe not exactly what you're looking for, but here's a somewhat related question:

Backbone.Marionette, collection items in a grid (no table)

My solution to that issue -- one fetched collection that could be rendered as a list or a grid ("items grouped in rows") was to use _.groupBy() in a "wrapper" CompositeView and pass modified data down the chain to another CompositeView (row) and then down to an ItemView.

Views.Grid = Backbone.Marionette.CompositeView.extend({
    template: "#grid-template",
    itemView: Views.GridRow,
    itemViewContainer: "section",
    initialize: function() {
        var grid = this.collection.groupBy(function(list, iterator) {
            return Math.floor(iterator / 4); // 4 == number of columns
        });
        this.collection = new Backbone.Collection(_.toArray(grid));
    }
});

Here's a demo:

http://jsfiddle.net/bryanbuchs/c72Vg/

like image 60
bryanbuchs Avatar answered Sep 25 '22 12:09

bryanbuchs


I've done both of the things your suggesting, and they both work well. It largely comes down to which one you prefer and maybe which one fits your scenario better.

If you have data that is already in a grouped hierarchy, using one of the many hierarchical model / collection plugins or your own hierarchy code, then the idea of rendering a list of groups, with each group rendering a list of items is probably easier.

If you have data that is flat, but contain a field that you will group by, then the appendHtml changes will probably be easier.

hth

like image 20
Derick Bailey Avatar answered Sep 23 '22 12:09

Derick Bailey