我正在尝试在 Ember.js 中实现“分组依据”功能,事实证明它比我最初想象的要困难。
[{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'}]
我正在寻找与此类似的最终输出:
Today
----------
4:22 pm - Tidal wave occurred
5:00 am - Tornado destroyed town
Monday
----------
2:22 pm - Volcanic eruption, likely
...etc., etc.
现在该数据已绑定(bind)到 ArrayController。每个对象都有一个计算属性,用于获取“年/月/日”进行分组比较。
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.[]')
});
关于实现这一点的最佳方法有什么建议吗? Ember 附带了filterBy 和mapBy,但没有groupBy。
最佳答案
这是我稍作修改的可分组实现:
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 使用:
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)'
模板用法:
{{#each groupedContent}}
{{group.key}} - {{group.description}}
{{#each content}}
Here's the really bad thing that happened: {{message}}
{{/each}}
{{/each}}
本质上,Groupable mixin 所做的就是循环遍历普通内容 ArrayProxy 并调用一个函数来确定它属于哪个组。如果该组对象尚不存在(即未找到匹配的group.key
),则会在将当前内容项添加到组内容之前创建该对象。 p>
因此,您在模板中最终得到的是对象 (Ember.Object
) 的新数组 (ArrayProxy
),每个对象都有一个组
属性(必须至少有一个 key
属性来标识它)和一个 content
属性(包含属于该组的内容)。
关于Ember.js 分组结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21143843/