11

Every google result is about an ArrayController sorting. Need a sorting mechanism without using ArrayController.

There is a model where there are sort params. Like say 'sortOrder' as one of the properties in the model (which will be from a back end).

Will be rendering this model using #each but this should do the iteration based on the sortOrder property and not the model's ID property.

2
  • Sorting mechanism: stuff.sort(). (Vague question, useless answer. You might want to expand on your use case. What do you want sorted, for starters? How will you use it?) Commented May 22, 2015 at 2:24
  • stackoverflow.com/questions/18855942/… Commented May 22, 2015 at 2:36

4 Answers 4

31

In Ember 2.0 SortableMixin is deprecated and is on its way out too.

In the Controller (not the ArrayController) you may define a new computed property like SortedUsers1,2,3 below:

export default Ember.Controller.extend({
    sortProps: ['lastName'],
    sortedUsers1: Ember.computed.sort('model', 'sortProps'),
    sortedUsers2: Ember.computed.sort('content', 'sortProps'),
    sortedUsers3: Ember.computed('content', function(){
        return this.get('content').sortBy('lastName');
    })
});

The assumption above is that the model itself is an array of users with lastName as one of user properties. Dependency on 'model' and 'content' look equivalent to me. All three computed properties above produce the same sorted list.

Note that you cannot replace 'sortProps' argument with 'lastName' in sortedUsers1,2 - it won't work.

To change sorting order modify sortProps to

sortProps: ['lastName:desc']

Also if your template is in users/index folder then your controller must be there as well. The controller in users/ would not do, even if the route loading model is in users/.

In the template the usage is as expected:

    <ul>
        {{#each sortedUsers1 as |user|}}
            <li>{{user.lastName}}</li>
        {{/each}}
    </ul>
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for this! I saw that ArrayController will be deprecated in 2.0, but nowhere in the docs does it explain how to migrate the sorting. (Except vague mentions of the SortableMixin, which hasn't yet been marked as deprecated in the api docs). And this answer is the only place I could find that explains an alternative.
I'm exactly in the same boat, learning this stuff and hitting walls left and right. Ember 2.0 deprecates a lot of stuff, but it's often not clear what to use instead (unless you closely follow Ember development which most of us don't).
If you're looking to future-proof your code, it's worth remembering that controllers themselves are on the way out and this solution too will eventually stop working.
How to make a refresh #each list after changing sort property on model?
I abandoned Ember a while back as I didn't like how complexity grows in the system over time, so cannot help with that. Hopefully somebody from the community may answer. Or maybe it's easier just to make a new question in order to be noticed sooner. Sorry.
7

Here is how I manually sort (using ember compare)

import Ember from "ember";
import { attr, Model } from "ember-cli-simple-store/model";

var compare = Ember.compare, get = Ember.get;

var Foo = Model.extend({
    orderedThings: function() {
        var things = this.get("things");
        return things.toArray().sort(function(a, b) {
            return compare(get(a, "something"), get(b, "something"));
        });
    }.property("[email protected]")
});

3 Comments

Thank you @toranb. Which do you think is a better way?
@AryStark just depends on your version of ember/if you are using an ArrayController or if you are in latest ember (not using SortableMixin for example). Both are valid - I was hoping to show the "from scratch" version :)
This is better than a computed on a controller, because in theory you can have your data sorted everywhere you access it. Actually could you have an adapter in ember-data that sorts it when received from the api? Would it stay sorted in the store?
3

You just need to include a SortableMixin to either controller or component and then specify the sortAscending and sortProperties property.

Em.Controller.extend(Em.SortableMixin, {
  sortAscending: true,
  sortProperties: ['val']
});

Here is a working demo.

2 Comments

These days, you should use computed properties, as described in the answer below.
0

In situations like that, I use Ember.ArrayProxy with a Ember.SortableMixin directly.

An ArrayProxy wraps any other object that implements Ember.Array and/or Ember.MutableArray, forwarding all requests. This makes it very useful for a number of binding use cases or other cases where being able to swap out the underlying array is useful.

So for example, I may have a controller property as such:

sortedItems: function(){
        var items = Ember.ArrayProxy.extend(Ember.SortableMixin).create({content: this.get('someCollection')});
        items.set('sortProperties', ['propNameToSortOn']);
        return items;
}.property()

Like so: JSBin

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.