ArrayController content sorting

I have an Ember.ArrayController that has unsorted content.

I want to know if it is possible to sort the contents of an ArrayController without using a new property.

I could, of course, create a new property:

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

But I hope that there is a better way that does not duplicate content.

+8
sorting arrays
source share
2 answers

UPDATE

The latest version of Ember has built-in sorting. ArrayController now includes Ember.SortableMixin , which will be enabled if you specify sortProperties (Array) and optionally sortAscending (Boolean).

Note: with the new SortableMixin, you still need to refer to arrangedContent to get a sorted version. The model itself will remain untouched. (Thanks to Jonathan Tran)

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

ORIGINAL RESPONSE

The proper way to do this is to use the arrangedContent property for ArrayProxy. This property is intended to be overridden to provide a sorted or filtered version of the content array.

 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() }); 
+35
source share

You must manually sort the arrays, including the contents of the array controller, in Ember. You can always replace content with your sorted array without saving both arrays.

Update

Here is an example of what I think you are looking for: http://jsfiddle.net/ud3323/yjs8D/

Update # 2

This example has been updated to take advantage of new changes to the presentation context. https://gist.github.com/2494968

Rudders

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

+2
source share

All Articles