简体   繁体   English

Ember.js:对模型进行分组(使用ArrayProxy)

[英]Ember.js: Group a model (using ArrayProxy)

I have an array whose items I want to group, and then display in this grouped fashion. 我有一个数组,其项目我想分组,然后以这种分组方式显示。 It's all terribly confusing: 这一切都非常令人困惑:

App.GroupedThings = Ember.ArrayProxy.extend({
  init: function(modelToStartWith) {
    this.set('content', Ember.A());        
    this.itemsByGroup = {};  

    modelToStartWith.addArrayObserver(this, {      
      willChange: function(array, offset, removeCount, addCount) {},
      didChange: function(array, offset, removeCount, addCount) {
        if (addCount > 0)
          // Sort the newly added items into groups
          this.add(array.slice(offset, offset + addCount))
      }
    });
  },

  add : function(things) {
    var this$ = this;

    // Group all passed things by day    
    things.forEach(function(thing) {
      var groupKey = thing.get('date').clone().hours(0).minutes(0).seconds(0);

      // Create data structure for new groups
      if (!this$.itemsByGroup[groupKey]) {
        var newArray = Ember.A();
        this$.itemsByGroup[groupKey] = newArray;
        this$.get('content').pushObject({'date': groupKey, 'items': newArray});
      }

      // Add to correct group
      this$.itemsByGroup[groupKey].pushObject(thing);
    });
  }
});


App.ThingsRoute = Ember.Route.extend({
  model: function() {
    return new App.GroupedThings(this.store.find('thing'));
  },
});

This only works if I use the following template: 这仅在我使用以下模板时有效:

{{#each model.content }}

These don't render anything (an ArrayController is used): 这些不呈现任何东西(使用ArrayController):

{{#each model }}
{{#each content }}
{{#each}}

Why? 为什么? Shouldn't the ArrayController proxy to "model" (which is GroupedThings), which should proxy to "content"? 不应该将ArrayController代理转换为“模型”(这是GroupedThings),它应该代理到“内容”?

The reason this becomes a problem is that I then want to sort these groups, and as soon as I change the entire contents array (even using ArrayProxy.replaceContent()), the whole views rebuilt, even if only a single item is added to a single group. 这成为一个问题的原因是我想要对这些组进行排序,一旦我更改整个内容数组(甚至使用ArrayProxy.replaceContent()),整个视图就会重建,即使只添加了一个项目一个小组。

Is there a different approach to this entirely? 完全有不同的方法吗?

I've tended to use ArrayProxies slightly differently when doing such things. 在做这些事情时,我倾向于稍微使用ArrayProxies。 I'd probably get Ember to do all the heavy lifting, and for sorting get it to create ArrayProxies based around a content collection, that way you can sort them automatically: 我可能会让Ember做所有繁重的工作,并且为了排序让它根据内容集创建ArrayProxies,这样你就可以自动对它们进行排序:

(note I haven't run this code, but it should push you off in the right direction) (注意我没有运行此代码,但它应该将你推向正确的方向)

App.GroupedThings = Em.ArrayProxy.extend({
  groupKey: null,
  sortKey: null,
  groupedContent: function() {
    var content = this.get('content');
    var groupKey = this.get('groupKey');
    var sortKey = this.get('sortKey');
    var groupedArrayProxies = content.reduce(function(previousValue, item) {
      // previousValue is the reduced value - ie the 'memo' or 'sum' if you will
      var itemGroupKeyValue = item.get('groupKey');
      currentArrayProxyForGroupKeyValue = previousValue.get(itemGroupKeyValue);
      // if there is no Array Proxy set up for this item's groupKey value, create one
      if(Em.isEmpty(currentArrayProxyForGroupKeyValue)) {
        var newArrayProxy = Em.ArrayProxy.createWithMixins(Em.SortableMixin, {sortProperties: [sortKey], content: Em.A()});
        previousValue.set(itemGroupKeyValue, newArrayProxy);
        currentArrayProxyForGroupKeyValue = newArrayProxy;
      }
      currentArrayProxyForGroupKeyValue.get('content').addObject(item);
      return previousValue;
    }, Em.Object.create());
    return groupedArrayProxies;
  }.property('content', 'groupKey', 'sortKey')
);

You'd then Create a GroupedThings instance like this: 然后你就像这样创建一个GroupedThings实例:

var aGroupedThings = App.GroupedThings.create({content: someArrayOfItemsThatYouWantGroupedThatHaveBothSortKeyAndGroupKeyAttributes, sortKey: 'someSortKey', groupKey: 'someGroupKey'});

If you wanted to get the groupedContent, you'd just get your instance and get.('groupedContent'). 如果你想获得分组内容,你只需要获得你的实例并获得。('groupsContent')。 Easy! 简单! :) :)

...and it'll just stay grouped and sorted (the power of computed properties)... if you want an 'add' convenience method you could add one to the Em.Object.Extend def above, but you can just as easily use the native ones in Em.ArrayProxy, which are better IMHO: ...它只会保持分组和排序(计算属性的强大功能)...如果你想要一个'add'方便方法,你可以在上面添加一个Em.Object.Extend def,但你可以像很容易使用Em.ArrayProxy中的原生代码,这是更好的恕我直言:

aGroupedThings.addObjects([some, set, of, objects]);

or 要么

aGroupedThings.addObject(aSingleObject);

H2H H2H

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM