I have to access a property that is two level's deep on my controller, but the []
only can access one level deep via the emberjs guide.
model(params) {
params.paramMapping = {
page: "page",
perPage: "per_page",
total_pages: "pages"
};
return this.findPaged('contractf', params);
},
setupController(controller, model) {
model.forEach(function(item) {
item.set('sale_price', item.get('dealers_sched_id.sale_price'));
});
controller.set('content', model);
},
Above, I have my model which is basically fetching all records in a pagination format in the contractf model. Then I set up my controller and loop through all those models and bind a sale_price
property that goes into it's relationship to get the sale_price in the correct model relation.
Now in my template, I have this:
new_suggested_price: Ember.computed('selectedItems', 'selectedItems.[].sale_price', function() {
var ret = 0;
this.get('selectedItems').filterBy('car_used', 'N').forEach(function(contract){
var salePrice = contract.get('sale_price');
if (salePrice) {
ret += (salePrice*100);
}
});
return ret/100; // We *100/100, so we avoid a floating point calc error.
}),
Basically just gives me a number that is easily format-able. As you can see it depends on the selectedItems (which is basically the model, but filters by a property). So I have to go into each model item and find that sale_price
I property I set and if it changes, this computed property will update. Reading Ember's guide, I couldn't do selectedItems.[].dealers_sched_id.sale_price
because it only goes one level deep.
I thought setting a property on setupController would fix that issue, but it doesn't seem to because I'm still getting NaN
as the sale_price
value.
Now if I set a setTimeout function for 500 ms, it populates fine.. How do I get it defined on page load?
Thank you for any help.
Ember API indeed allows you to use only one level of @each
/[]
in your computed property dependencies.
This limitation is likely artificial as using two or more @each
levels is a huge performance impact on internal observer maintenance.
Thus, you have to avoid more than one @each
/[]
in your CP dependency chains.
But sometimes your business dictates you to have to or more levels.
Fear not! This can be achieved with a chain of computed properties, where each property has only one @each
level.
Say, you have Foo, Bar and Baz models and want to depend on
[email protected][email protected][email protected]
Here's a chain of computed properties you need to create:
barsArrays: computed('[email protected]')
-- map foos
by bars
. You'll have an array of arrays of bars.bars: computed('barsArrays.[]')
-- flatten it to receive an array of bars.bazesArrays: computed('[email protected]')
-- map bars
by bazes
.bazes: computed('bazesArrays.[]')
-- flatten bazesArrays
.bazesNames: computed('[email protected]')
-- map bazes
by name
.Note that you can make this chain shorter (but not necessarily more performant) by relying on the fact that bar.bazes
is a relationship array that is never replaced with a different array (only its content changes, but the array object stays the same).
bazesArrays: computed('[email protected]')
-- map foos
by bars
, flatten, then map by bazes
. You'll have an array of arrays of bazes.bazes: computed('bazesArrays.[]')
-- flatten bazesArrays
.bazesNames: computed('[email protected]')
-- map bazes
by name
.Here's a working demo: http://emberjs.jsbin.com/velayu/4/edit?html,js,output
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