ember.js: `{{#each item in array}}` does not rerender when the array is sorted and the change is properly notified

Here’s my demo code:

App.ApplicationController = Ember.Controller.extend({
    anArray: ['sleeping', 'eating pizza','programming', 'looking at lolcats'],

    actions: {
      sort: function() {

        var anArray = this.get("anArray");

        console.log('anArray in action (before):', anArray.join(', '));

        this.propertyWillChange('anArray');
        anArray.sort();
        this.propertyDidChange('anArray');

        console.log('anArray in action (after):', anArray.join(', '));
      }
    },

    someOtherArray: Ember.computed('anArray.[]', function() {
      var anArray = this.get('anArray');
      console.log('anArray in someOtherArray:', anArray.join(', '));
      return anArray;
    })
});

When i trigger the action, the array gets sorted.

I’ve created the second property to make sure that the first property does change. From console output you can see that the computed property receives a sorted value and it does recalculate on every button click.

But the sorting is not reflected on the page! =-O

Demo: http://emberjs.jsbin.com/mamiru/4/edit?html,js,output

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 25 (25 by maintainers)

Most upvoted comments

I changed

this.propertyWillChange('anArray');
anArray.sort();
this.propertyDidChange('anArray');

to this.set("anArray", anArray.sort().slice()); and worked. This is the new demo http://emberjs.jsbin.com/kezuqopaci/1/edit. Note that without slice the template is not updated, I believe that there is a cache layer in the template checking the new property with ===, and since anArray.sort() === anArray the template is not updated.