【问题标题】:Ember.js: Group a model (using ArrayProxy)Ember.js:对模型进行分组(使用 ArrayProxy)
【发布时间】:2013-12-06 22:30:48
【问题描述】:

我有一个数组,我想将其项目分组,然后以这种分组方式显示。这一切都非常令人困惑:

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),而应该代理“content”吗?

这成为问题的原因是我想要对这些组进行排序,并且一旦我更改整个内容数组(即使使用 ArrayProxy.replaceContent()),整个视图都会重新构建,即使只有一个项目被添加到单个组中。

有完全不同的方法吗?

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    在做这些事情时,我倾向于使用稍微不同的 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

    【讨论】:

      猜你喜欢
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 1970-01-01
      相关资源
      最近更新 更多