Skip to content

Instantly share code, notes, and snippets.

@apiv
Last active August 29, 2015 14:08
Show Gist options
  • Save apiv/6e26ed7e6a3e4da63b9c to your computer and use it in GitHub Desktop.
Save apiv/6e26ed7e6a3e4da63b9c to your computer and use it in GitHub Desktop.
A rough write-up of Backbone.GroupedCollection
class Backbone.Group extends Backbone.Model
constructor: ->
@childCollection = new Backbone.Collection
super
class Backbone.Grouped extends Backbone.Model
## Override Me
childGroupBy: (model)->
## You can override this too
childModel: Backbone.Model
constructor: ->
GroupCollection = Backbone.Collection.extend(model: Backbone.Group)
@childCollection = new GroupCollection
super
## Ensures that a group exists for a given index
_ensureGroup: (index)->
group = @childCollection.find(index)
if !group
group = new @childCollection.model(id: index)
@childCollection.add([group])
group
## Ensures that the object passed is an instance of @this.model
## Used in preparation for grouping (where all objects must be a model)
_ensureModel: (objectOrModel)->
if !(objectOrModel instanceof(Backbone.Model))
new @childModel(objectOrModel)
else
objectOrModel
## Groups the given model or models
_groupModels: (models=[])->
models = _.toArray(models)
models = _.map models, (model)=> @_ensureModel(model)
_.groupBy models, @childGroupBy
add: (models=[], options={})->
grouped = @_groupModels(models)
for groupIndex, models of grouped
group = @_ensureGroup(groupIndex)
group.childCollection.add(models, options)
reset: (models=[], options={})->
grouped = @_groupModels(models)
for groupIndex, models of grouped
group = @_ensureGroup(groupIndex)
group.childCollection.reset(models, options)
remove: (models=[], options={})->
grouped = @_groupModels(models)
for groupIndex, models of grouped
group = @_ensureGroup(groupIndex)
group.childCollection.remove(models, options)
class Quarter extends Backbone.Grouped
childGroupBy: (model)->
moment(model.get('date'))
.startOf('day')
class Timeline extends Backbone.Grouped
childModel: Quarter
childGroupBy: (model)->
moment(model.get('date'))
.startOf('quarter')
timeline = new Timeline()
timeline.reset([{date: new Date, title: 'Yo yo yo'}, {date: moment().subtract(6, 'months').toDate(), title: 'Ay'}])
class TimelineItem extends Marionette.ItemView
tagName: 'li'
template: _.template("<%= title %>")
class DayView extends Marionette.CompositeView
tagName: 'li'
template: _.template("Day<ul></ul>")
childView: TimelineItem
childViewContainer: 'ul'
class QuarterView extends Marionette.CompositeView
tagName: 'li'
template: _.template("Quarter<ul></ul>")
childView: DayView
childViewContainer: 'ul'
childViewOptions: (model)->
collection: model.childCollection
class TimelineView extends Marionette.CompositeView
tagName: 'div'
template: _.template("<ul></ul>")
childView: QuarterView
childViewContainer: 'ul'
childViewOptions: (model)->
collection: model.childCollection
timelineView = new TimelineView(model: timeline, collection: timeline.childCollection)
timelineView.$el.appendTo('body')
timelineView.render()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment