Search code examples
propertiesember.jsobservers

Ember.js: Too weird - property skipped when name is changed


I have two computed properties, both of which are functioning normally. But when I change the name of the property (and nothing else) ember no longer triggers them.

I am not changing the properties they observe so it does not make sense that changing the name of the property would make any difference. Likewise, when I create more computed properties that watch the same property, those are never hit. WTF??

Screen cast: http://screencast.com/t/YXQDMprzSFW - see it work (and not)

Properties of this model: focusing on selectedQuantity and selectedCost

App.Item = Ember.Object.extend({

    // item descriptive properties
    identity: 'model: Item',
    id: '',                                             // numeric id matching node id
    slug: '',                                           // identifier suitable for css classes
    title: '',
    subtitle: '',
    description: '',
    image: '',
    category: '', 
    isActive: false,

    // item data collections
    options: [],
    properties: [],

    // flag to indicate a change in option selections

    // percent of VEC portfolio
    percentVec: function(){
        var p = this.get('values').findBy('type', 'percentVec');
        if(typeof p != 'undefined') { p = parseInt(p.quantity, 10); }
        else { p = ''; }
        return p;
    }.property('values.@each'),

    // current quantity
    selectedQuantity: function(){
        var opt = this.get('options').findBy('isSelected', true); 
        var q = (typeof opt != 'undefined') ? opt.get('quantity') : 0; 
        return parseInt(q, 10);
    }.property('[email protected]'),

    // current cost
    selectedCost: function(){
        var j = this.get('options').reduce(function(prevCost, currentOption, index, array){ 
            if(currentOption.get('isSelected')) return currentOption.get('cost');
            else return prevCost;
        }, 0);
        return j;
    }.property('[email protected]'), 

    // localized base cost
    vtCost: function(){
        var c = this.get('values').findBy('type', 'costVt');
        if(typeof c != 'undefined') { c = parseInt(c.cost, 10); } 
        else { c = ''; }
        return c;
    }.property('values.@each')

})
.reopen({

    hasProperty: function( prop ){
        var properties = this.get('properties');
        return (typeof properties[prop] != 'undefined') ? true : false;
    }

});

This doesn't feel like a coding problem - feels more like a caching problem or something, but I can't figure it out.


Solution

  • That is normal.

    Those are computed properties. You are most likely rendering both computed properties like this {{selectedCost}} & {{selectedQuantity}} in your handlebars template.

    Renaming one of those only in your controller causes ember not computing, since they aren't needed.

    You could always use .observers(..) if you want to respond on a changed value.

    Edit Also note,

    Declaring your object like this:

    App.Item = Ember.Object.extend({
    
        // item descriptive properties
        identity: 'model: Item',
        ...
    }
    

    Means that your identity field is shared between all App.Items. Make sure to use the set function. Eg: this.set('identity','model: Item')