Evan M
Evan M

Reputation: 2611

Ember template not updating when array in model is modified

I have a simple array of ints that I'm displaying on a page.

This is my model:

var Favorite = Ember.Object.extend({
    stuff: Ember.A([1,2,3,4])
});

This is my template:

{{#each model.stuff as |num|}}
    <li>{{num}}</li>
{{/each}}

In my controller, modifications to this array generally display on the page (such as pushObject()), but modifying elements directly does not cause the page to update. I have a button on my page linked to this controller action:

actions: {
    arrayAdd() {
        this.get('model').stuff[0] = 100;
    }
}

Clicking the button modifies the underlying array, but doesn't update the page. Is there a way to have ember automatically pick up on that change?

I'm doing this in Ember 1.13

Upvotes: 0

Views: 1453

Answers (2)

Lux
Lux

Reputation: 18240

Actually the equivalent of arr[idx] = foo for an ember array is arr.replace(idx, 1, [foo]).

The other thing you could do is to call this.get('model').notifyPropertyChange('stuff') after you manually edited the array.

Upvotes: 1

Ember Freak
Ember Freak

Reputation: 12872

In Ember, you need to use KVO(key value observer) compliant methods so that it will trigger computed property recalculation and observer and update the template. Always we need to use get for getting the properties and set for setting the values. if you didn't follow ember will throw assertion error sometime.

For array there are KVO methods which is equivalent to standard method.

Standard Method ->  Observable Equivalent
pop ->  popObject
push -> pushObject
reverse ->  reverseObjects
shift -> shiftObject
unshift -> unshiftObject

In your case, you need to update it like the below, reference twiddle

arrayAdd() {
        this.get('model.stuff').unshiftObject(100);
    }

Note: You can declare array stuff: [1,2,3,4] it's good to initialize it in init method.

I still feel the array indexer should properly update the value, though

Interestingly in glimmer component, you don't need to use getters/setters.

Upvotes: 0

Related Questions