Ember.js Grouping Results
ember.js
Solution
Here's a Groupable implementation I've adapted a bit:
Groupable = Ember.Mixin.create
group: null
ungroupedContent: null
groupedContent: (->
model = @
groupedContent = Ember.A([])
groupCallback = @get('group')
ungroupedContent = @get('ungroupedContent')
return groupedContent unless groupCallback
return groupedContent unless ungroupedContent
ungroupedContent.forEach (item) ->
group = groupCallback.call(model, item)
return unless groupKey = group.get('key')
foundGroup = groupedContent.findProperty('group.key', groupKey)
unless foundGroup
foundGroup = groupedContent.pushObject Ember.ArrayProxy.create
group: group,
content: Ember.A([])
foundGroup.get('content').pushObject(item)
groupedContent
).property('group', 'ungroupedContent.@each')
Controller usage:
ActivitiesController = Ember.ArrayController.extend Groupable,
ungroupedContentBinding: 'content' # tell Groupable where your default content is
# the callback that will be called for every
# item in your content array -
# just return the same 'key' to put it in the same group
group: (activity) ->
Ember.Object.create
key: moment.utc(activity.get('date')).format('YYYY-MM-DD') # using momentjs to pluck the day from the date
description: 'some string describing this group (if you want)'
Template usage:
{{#each groupedContent}}
{{group.key}} - {{group.description}}
{{#each content}}
Here's the really bad thing that happened: {{message}}
{{/each}}
{{/each}}
Essentially, all that the Groupable mixin does is loop through your normal content ArrayProxy and calls a function to determine what group it belongs to. If that group object doesn't already exist (i.e. no matching `group.key` was found), it creates it before adding the current content item to the group's content.
So what you end up with in your template is a new array (`ArrayProxy`) of objects (`Ember.Object`), with each object having a `group` property (which must have at least a `key` property to identify it) and a `content` property (which contains the content belonging to that group).
Problem
I'm trying to achieve a "group by" functionality in Ember.js and its proving more difficult than I originally thought. ``` [{date: '2014-01-15T16:22:16-08:00', message: 'Tidal wave occurred'}, {date: '2014-01-15T05:00:16-08:00', message: 'Tornado destroyed town'}, {date: '2014-01-13T14:22:16-08:00', message: 'Volcanic eruption, likely'}, {date: '2014-01-13T16:24:16-08:00', message: 'Ice shelf calving off completely'}, {date: '2014-01-11T11:27:26-08:00', message: 'Mother-in-law visiting'}] ``` I'm looking for final output similar to this: ``` Today ---------- 4:22 pm - Tidal wave occurred 5:00 am - Tornado destroyed town Monday ---------- 2:22 pm - Volcanic eruption, likely ...etc., etc. ``` Right now this data is bound to an ArrayController. Each object has a computed property to get "year/month/day" for the grouping comparison. ``` var ActivityController = Em.ArrayController.extend({ groupedResults: function () { var result = []; //Iterate over each item in the list, but do what with it? this.get('content').filter(function (item) { }); return result; }.property('content.[]') }); ``` Any tips on the best way to implement this? Ember ships with filterBy and mapBy, but no groupBy.