I'm not too entirely sure why my computed property isn't returning updated values.
I have a list of options that a user can click through, and the action updates a property, which is an Ember Object, for the controller. I have a computed property that loops through the object, looks for keys that have non-null values for that Ember Object property, and if it does find one, returns false, otherwise true.
Here's the stuff:
App.SimpleSearch = Ember.Object.extend({
init: function() {
this._super();
this.selectedOptions = Ember.Object.create({
"Application" : null,
"Installation" : null,
"Certification" : null,
"Recessed Mount" : null,
"Width" : null,
"Height" : null,
"Heating" : null,
"Power" : null
});
},
selectedOptions: {},
numOfOptions: 0,
allOptionsSelected: function() {
var selectedOptions = this.get('selectedOptions');
for (var option in selectedOptions) {
console.log(selectedOptions.hasOwnProperty(option));
console.log(selectedOptions[option] === null);
if (selectedOptions.hasOwnProperty(option)
&& selectedOptions[option] === null) return false;
}
return true;
}.property('selectedOptions')
});
App.SimpleSearchRoute = Ember.Route.extend({
model: function() {
return App.SimpleSearch.create({
'SimpleSearchOptions': App.SimpleSearchOptions,
'numOfOptions': App.SimpleSearchOptions.length
});
},
setupController: function(controller, model) {
controller.set('model', model);
}
});
App.SimpleSearchController = Ember.ObjectController.extend({
getProductsResult: function() {
var productsFromQuery;
return productsFromQuery;
},
setSelection: function (option, selectionValue) {
this.get('selectedOptions').set(option, selectionValue);
this.notifyPropertyChange('allOptionsSelected');
},
actions: {
registerSelection: function(option) {
console.log('registering selection');
console.log(this.get('allOptionsSelected'));
console.log(this.get('selectedOptions'));
this.setSelection(option.qname, option.value);
},
The action in the controller, registerSelection
is firing just fine, but I only see the console.log
from the SimpleSearch
model once. Once the property is computed that first time, it isn't paid attention to after that, which means that the computed property isn't observing the changes to selectedOptions
whenever this is called:
setSelection: function (option, selectionValue) {
this.get('selectedOptions').set(option, selectionValue);
this.notifyPropertyChange('allOptionsSelected');
},
Edit:
I actually solved my issue without changing anything.
I've changed the following line:
this.notifyPropertyChange('allOptionsSelected');
to:
this.get('model').notifyPropertyChange('selectedOptions');
notifyPropertyChange
needs to be called within the context of the model (or the Ember Object that has observers of a specific property), and the string sent as an argument is the name of the property that was updated.
After I made that change, it worked as intended.
Ember doesn't observe objects for any change on the object, it observes a single property.
How is this affecting you? Well in this method you are watching selectedOptions
, but that object itself is still the same object, you might be changing properties on it, but not the object itself. And then you are telling Ember in the scope of the controller that allOptionsSelected
has changed, so it regrabs it, but it doesn't recalculate it because it's not dirty, it just changed. You'd really want to say selectedOptions
has changed to get allOptionsSelected
to recalculate its value. Unfortunately you're doing this in the scope of the controller, so telling the controller that property has changed doesn't matter to it.
allOptionsSelected: function() {
var selectedOptions = this.get('selectedOptions');
for (var option in selectedOptions) {
console.log(selectedOptions.hasOwnProperty(option));
console.log(selectedOptions[option] === null);
if (selectedOptions.hasOwnProperty(option)
&& selectedOptions[option] === null) return false;
}
return true;
}.property('selectedOptions')
Here's a dummy example showing what things cause it to actually update.
http://emberjs.jsbin.com/iCoRUqoB/1/edit
Honestly since you're not watching particular properties I'd probably do an array, or create a method on the object that handles adding/removing/modifying the properties so you could fire from within it's scope a property change updating all parent listeners with the changes.
Ember computed property dependent keys can be a
Example extracted from Ember.model definition:
...
jobTitle : DS.attr('string'),
salesAccount: belongsTo('salesAccount'),
companyName: Ember.computed('jobTitle', 'salesAccount.name', {
get: function () {
return this.get('salesAccount.name');
}
}),
companyWebsite: Ember.computed('salesAccount.website', 'companyName', {
get: function () {
return this.get('salesAccount.website');
}
})
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With