Сортировать содержимое ArrayController

У меня естьEmber.ArrayController с несортированным содержимым.

Я хочу знать, возможно ли отсортировать содержимое ArrayController без использования нового свойства.

Конечно, я могу создать новое свойство:

<code>App.MyArrayController = Em.ArrayController.extend({
  mySortMethod: function(obj1, obj2) {
    // some code here
  },
  updateSortedContent: function() {
    var content = this.get('content');
    if (content) {
      var sortedContent = content.copy();
      sortedContent.sort(this.mySortMethod);
      this.set('sortedContent', sortedContent);
    }
  }.observes('content')
});
</code>

Но я надеюсь, что есть лучший способ, который не дублирует контент.

 Willem de Wit22 нояб. 2013 г., 09:42

Ответы на вопрос(2)

Решение Вопроса

ОБНОВИТ

В последней версии Ember встроена сортировка.ArrayController теперь включает в себяEmber.SortableMixin который будет задействован, если вы укажетеsortProperties (Массив) и, необязательно,sortAscending (Логическое).

Примечание: с новым SortableMixin вам все еще нужно обратиться кarrangedContent чтобы получить отсортированную версию. Сама модель останется нетронутой. (Спасибо Джонатану Трану

App.userController = Ember.ArrayController.create({
  content: [],
  sortProperties: ['age'],
  sortAscending: false
})

ОРИГИНАЛЬНЫЙ ОТВЕТ

Правильный способ сделать это - использоватьarrangedContent свойство ArrayProxy. Это свойство предназначено для переопределения для предоставления отсортированной или отфильтрованной версии массива содержимого.

App.userController = Ember.ArrayController.create({
  content: [],
  sort: "desc",
  arrangedContent: Ember.computed("content", function() {
    var content, sortedContent;
    content = this.get("content");
    if (content) {
      if (this.get("sort") === "desc") {
        this.set("sort", "asc");
        sortedContent = content.sort(function(a, b) {
          return a.get("age") - b.get("age");
        });
      } else {
        this.set("sort", "desc");
        sortedContent = content.sort(function(a, b) {
          return b.get("age") - a.get("age");
        });
      }
      return sortedContent;
    } else {
      return null;
    }
  }).cacheable()
});
 Jonathan Tran13 апр. 2013 г., 23:20
Примечание: с новым SortableMixin вам все еще нужно обратиться кarrangedContent чтобы получить отсортированную версию. Это споткнуло меня вначале.
 Sam Selikoff29 июл. 2013 г., 23:32
@ louiscoquio не хотите обновить правильный ответ?
 Jonathan Tran16 дек. 2014 г., 21:36
@ SatA В вашем шаблоне или там, где вам нужна отсортированная версия, не используйтеcontent. Это исходный массив моделей, и он не будет отсортирован.
 Rajat25 авг. 2012 г., 10:58
Определение sortProperty сортирует по умолчанию. Можно ли это изменить, чтобы адаптировать сортировку только тогда, когда пользовательский запрос зарегистрирован (через выпадающий список или что-то в этом роде)?
 Martin Westin18 сент. 2012 г., 20:34
Вы определяете свойства сортировки по умолчанию, чтобы они были «нормальными» для вашего контента. Затем вы делаете небольшое действие, которое изменяет эти два свойства с помощью bu, ttons или раскрывающихся списков, и происходит волшебство. У меня есть метод reSort на контроллере, который устанавливает свойство сортировки (я использую только одно) на то, что кнопка отправляет в качестве аргумента. И если свойство совпадает с уже установленным, оно интерпретирует это как указание изменить порядок на нисходящий. Gist.github.com / 3744939

включая содержимое любого контроллера массива, в Ember. Вы всегда можете заменитьcontent с вашим отсортированным массивом вместо хранения обоих массивов.

Обновит

Вот пример того, что, я думаю, ты ищешь:http: //jsfiddle.net/ud3323/yjs8D

Обновление # 2

Обновлен этот пример, чтобы использовать новые изменения контекста представления.https: //gist.github.com/249496

Рули

<script type="text/x-handlebars" >
Will Display and Sort by Age (after 2 sec)<br/><br/>

{{#each App.userController}}
    {{#view App.RecordView}}
        {{name}} - {{age}}
    {{/view}}
{{/each}}
</script>

JavaScript

App = Ember.Application.create({
    ready: function() {
        Ember.run.later(this, function() {
            Ember.run.later(this, function() {
                App.get('userController').set('content', [
                   Ember.Object.create({ name:"Jeff", age:24 }),
                   Ember.Object.create({ name:"Sue", age:32 }),
                   Ember.Object.create({ name:"Jim", age:12 })
               ]);
      }, 2000);
        Ember.run.later(this, function() {
            // Make the controller's content sort again in reverse this time
            App.userController.notifyPropertyChange('content');
        }, 4000);
    }
});

App.userController = Ember.ArrayController.create({
    content: [],

    contentDidChange: Ember.observer(function(userCtr, prop) {
        if(!Ember.empty(this.get('content'))) {
            console.log('about to begin sort');
            this.sortContent();
        }

        this._super();
    }, 'content'),

    sort:"desc",

    sortContent:function() {
        var content = this.get("content"), sortedContent;

        if (this.get("sort") == "desc") {
            this.set("sort", "asc");
            sortedContent = content.sort( function(a,b){
                return a.get("age") - b.get("age");
            });
        } else {
            this.set("sort","desc");
            sortedContent = content.sort( function(a,b){
                return b.get("age") - a.get("age");
            });
        }

        this.set("content",sortedContent);
    }
});

App.RecordView = Ember.View.extend({});

 louiscoquio10 мая 2012 г., 20:20
оно работает! Я уже пробовал это, но я позвонилthis._super() перед сортировкой контента, чтобы он не работал. В любом случае, благодарю Ва
 Roy Daniels08 мая 2012 г., 22:16
Смотри мое обновление. Это решает эту проблему.
 louiscoquio08 мая 2012 г., 16:51
Да, но я не знаю, где его заменить, потому что если «контент» наблюдатель заменит контент, обратный вызов будет отправлен снова, и снова, и снова, ...
 Roy Daniels10 мая 2012 г., 22:06
Да, это недокументированная маленькая Эмбер Гоча. Вы должны позвонить_super() в конце, потому чтоcontentDidChange определено вEmber.ArrayProxy добавит наблюдателей наcontent свойство, котороеEmber.ArrayProxy нужно. Итак, хитрость в том, что вы хотите изменитьcontent прежде чем вы добавите этих наблюдателей, или вы столкнетесь с проблемой бесконечного цикла, звучит так, будто вы уже испытали это;)

Ваш ответ на вопрос