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

3

我有一个数组,想要将其中的项进行分组并以这种方式显示。这非常令人困惑:

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'));
  },
});

只有在使用以下模板时才能实现这个功能:

{{#each model.content }}

这些不会渲染任何内容(使用了ArrayController):

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

为什么?ArrayController不应该代理到“model”(即GroupedThings),而“model”应该代理到“content”吗?

这个问题的原因是,我想要对这些分组进行排序,但只要我更改整个contents数组(即使使用ArrayProxy.replaceContent()),整个视图都会被重建,即使只添加一个单独的项到一个单独的组中。

是否有完全不同的方法来解决这个问题?

1个回答

0

在做这样的事情时,我倾向于稍微不同地使用ArrayProxies。 我可能会让Ember来完成所有繁重的工作,并为排序创建基于内容集合的ArrayProxies,这样你就可以自动对它们进行排序:

(请注意,我没有运行过这段代码,但它应该能指导你朝着正确的方向前进)

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')
);

然后,您可以像这样创建一个GroupedThings实例:

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

如果您想获取groupedContent,只需获取您的实例并获取。('groupedContent')。很容易!:)
...它将保持分组和排序(计算属性的力量)......如果您想要一个“添加”便捷方法,可以将其添加到Em.Object.Extend def中,但是您也可以轻松使用Em.ArrayProxy中的本机方法,这些方法在我看来更好:
aGroupedThings.addObjects([some, set, of, objects]);

或者

aGroupedThings.addObject(aSingleObject);

H2H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接