Ember.js Grouping Results

后端 未结 3 708
长发绾君心
长发绾君心 2021-02-04 18:49

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\',          


        
相关标签:
3条回答
  • 2021-02-04 18:58

    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).

    0 讨论(0)
  • 2021-02-04 19:10

    You can use Ember.computed.groupBy like this:

    ((Ember) ->
      # Example:
      #
      #   productsByCategory: Em.computed.groupBy 'products', 'category'
      #
      #   each view.productsByCategory
      #     category.name
      #     each content
      #       content.name
      #
      Ember.computed.groupBy = (collection, groupBy) ->
        dependentKey = "#{collection}.@each.#{groupBy}"
    
        Ember.computed dependentKey, ->
          result = []
          @get(collection).forEach (item) ->
            unless result.findBy groupBy, item.get(groupBy)
              data = content: []
              data[groupBy] = item.get(groupBy)
              result.pushObject Ember.Object.create(data)
            result.findBy(groupBy, item.get(groupBy)).get('content').pushObject item
          result
    ) Ember
    
    0 讨论(0)
  • 2021-02-04 19:13

    Here is an implementation, made available on Array objects:

    var groupByMethod = Ember.Mixin.create({
      groupBy: function(key) {        
        var result = [];
        var object, value;
    
        this.forEach(function(item) {
          value = item.get ? item.get(key) : item[key];
          object = result.findProperty('value', value);
          if (!object) {
            object = {
              value: value,
              items: []
            };
            result.push(object);
          }
          return object.items.push(item);
        });
    
        return result.getEach('items');
      }
    });
    
    groupByMethod.apply(Array.prototype);
    

    Usage:

    > var posts = [{id: 1, author: 'John'}, {id:2, author: 'Paul'}, {id:4, author: 'Paul'}, {id:5, authour: 'Tom'}];
    
    > posts.groupBy('author')
    

    usage example

    0 讨论(0)
提交回复
热议问题