通过sortProperty mixin对由Ember-Data支持的ArrayController进行排序

时间:2012-09-22 22:10:11

标签: ember.js ember-data

我希望能够对其内容来自余烬数据查询的ArrayController进行排序。不幸的是,sortProperty mixin在这种情况下似乎不起作用。

我希望能够做到以下几点:

App = Ember.Application.create();
App.store = DS.Store.create({ revision: 4});

App.Item = DS.Model.extend({
    id: DS.attr('string'),
    name: DS.attr('string')
});

App.store.createRecord(App.Item, {id: '4', name: 'banana' });
App.store.createRecord(App.Item, {id: '2', name: 'apple'});
App.store.createRecord(App.Item, {id: '6', name: 'spaghetti'}); 

App.ItemsController = Ember.ArrayController.create({
    content: App.store.findAll(App.Item),
    sortProperties: ['name']
});

使用最新版本的Ember和Ember-data,这会给出输出:

[ id: 4, name: banana ]

[ id: 2, name: apple ]

[ id: 6, name: spaghetti ]

此处的问题是App.store.findAll()返回RecordArray,其内容属性不仅仅是App.Item个实例的数组(在这种情况下,内容为[2,3,4])

要真正了解实例,我需要使用类似objectAt()的内容。但即使我从App.Item中提取RecordArray实例并将它们转储到普通数组中,事情也无法按预期工作。

我是否错过了显而易见的方法,或者这仅仅是框架的现状?我宁愿不必将我的所有模型复制为普通对象,只是为了对它们进行排序。

修改

我通过制作自己的自定义ArrayController解决了这个问题。如果事情如上所述,那将会很好。

编辑#2:

原始把手模板:

<script type="text/x-handlebars">
    {{#each App.ItemsController.content }}
        <p>[ id: {{id}}, name: {{name}} ]</p>
    {{/each}}
</script>

(另外,我在上面的代码中使用了sortProperty属性而不是sortProperties,但这只是一个错字。)

是的,如果一个人使用

<script type="text/x-handlebars">
    {{#each App.ItemsController.arrangedContent }}
        <p>[ id: {{id}}, name: {{name}} ]</p>
    {{/each}}
</script>

然后我们得到了我们想要的东西:

[ id: 2, name: apple ]

[ id: 4, name: banana ]

[ id: 6, name: spaghetti ]

4 个答案:

答案 0 :(得分:11)

我遇到了同样的问题。我花了一段时间,但最终这个通用的解决方案解决了它:

App.ArrayController = Ember.ArrayController.extend({
  sortProperties: ['id'],
  sortAscending: true,

  sortedContent: (function() {
    var content;
    content = this.get("content") || [];
    return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
      content: content.toArray(),
      sortProperties: this.get('sortProperties'),
      sortAscending: this.get('sortAscending')
    });
  }).property("content.@each", 'sortProperties', 'sortAscending'),

  doSort: function(sortBy) {
    var previousSortBy;
    previousSortBy = this.get('sortProperties.0');
    if (sortBy === previousSortBy) {
      return this.set('sortAscending', !this.get('sortAscending'));
    } else {
      set('sortAscending', true);
      return this.set('sortProperties', [sortBy]);
    }
  }
});

现在我的大多数ArrayControllers扩展App.ArrayController而不是Ember.ArrayController,特别是那些以Ember / Data RecordArray为内容的扩展。

现在,在您的车把模板中,执行以下操作:

 {{#each item in sortedContent}}
   ...          
 {{/each}}

而不是

 {{#each item in content}}
   ...          
 {{/each}}

答案 1 :(得分:6)

从Ember 1.1.2和ember-data 1.0.0-beta.3开始,可能更早,只需在Controller上设置sortProperties即可。 sortAscending可以设置为truefalse,具体取决于您要排序的方向。

App.ArrayController = Ember.ArrayController.extend({
  sortProperties: ['name'],
  sortAscending: true
})

但请注意

sortProperties: ['id']

似乎是词汇排序而不是数字排序。我通过created_at时间戳来绕过词法排序,但可能还有另一种方法。

答案 2 :(得分:4)

我有一个类似的问题,并通过docs for the array class进行整理 在我的路线中,我使用了sortBy()方法。所以在你的情况下它可能是像

App.store.findAll().sortBy('name');

我知道这是一个古老的问题,但要回答这个问题,以防有人像我一样偶然发现

答案 3 :(得分:3)

截至Ember版本1.0.0-rc.4 Ember.ArrayProxy.create(Ember.SortableMixin ....似乎不再起作用了。使用 Ember.ArrayProxy.createWithMixins(Ember.SortableMixin ....或使用Ember.ArrayController中的内置排序功能。