2012-05-08 3 views
8

У меня есть Ember.ArrayController, у которого есть несортированный контент.Сортировка содержимого ArrayController

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

Я мог бы, конечно, создать новое свойство:

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

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

+0

возможно дубликат [Сортировка массива объектов EmberJS имуществом] (http://stackoverflow.com/questions/9041505/sort-array-of-emberjs-objects-by-property) –

ответ

35

UPDATE

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

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

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() 
}); 
+0

Определение сортировки sort sort по умолчанию. Можно ли это изменить, чтобы адаптировать сортировку только тогда, когда зарегистрирован пользовательский запрос (через раскрывающийся список или что-то еще)? – Rajat

+0

Вы определяете свойства сортировки по умолчанию и возрастаете, чтобы быть тем, что «нормально» для вашего контента. Затем вы делаете небольшое действие, которое изменяет эти два свойства с помощью кнопок или выпадающих списков и магии. У меня есть метод reSort на контроллере, который устанавливает свойство sort (я использую только одно) для того, что кнопка отправляет в качестве аргумента. И если свойство совпадает с тем, которое уже установлено, оно интерпретирует это как указание изменить порядок на нисходящий. https://gist.github.com/3744939 –

+8

Примечание: с помощью новой SortableMixin вам все равно нужно обратиться к 'builtContent', чтобы получить отсортированную версию. Сначала это сбило меня с толку. –

2

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

Update

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

Update # 2

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

Рули

<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({}); 

+0

да, но я не знаю, где его заменить, потому что, если наблюдатель «контента» заменит контент, обратный вызов будет отправлен снова и снова, и снова, ... – louiscoquio

+0

См. мое обновление. Это решает эту проблему. –

+0

он работает! Я уже пробовал это, но я назвал 'this._super()' перед сортировкой содержимого, чтобы он не работал. В любом случае, спасибо – louiscoquio

Смежные вопросы