Reputation: 31779
I am trying to implement sorting + filtering into my array controller. Everything is working except my template doesn't seem to get the computed properties after a change the sort direction more than 2 times. Im not sure whats really going wrong or if its a bug.
Here is the relevant code and a failing bin(click the sort button multiple times, the template stops showing the computed properties from the item controller).
{{#each sortedContent}}
<li>{{title}} - {{symbol}}{{totalAmount}}</li>
{{/each}}
App.IndexController = Em.ArrayController.extend({
itemController: 'item',
filterText: '',
sortProperties: ['totalAmount:asc'],
sortedContent: Em.computed.sort('filteredContent', 'sortProperties'),
filteredContent: function() {
console.log('filter');
return this.filter(function(item) {
return item.get('title').indexOf(this.get('filterText')) >= 0;
}.bind(this));
}.property('filterText','@this'),
actions: {
sortBy: function() {
var direction = 'asc';
if(this.get('sortProperties.0').split(':')[1] === 'asc') {
direction = 'desc';
}
console.log('totalAmount:'+direction);
this.set('sortProperties', ['totalAmount:'+direction]);
}
}
});
App.ItemController = Em.ObjectController.extend({
totalAmount: Em.computed.alias('price.amount'),
symbol: Em.computed.alias('price.currency')
});
Upvotes: 3
Views: 1115
Reputation: 8301
Took me a while of staring at it, but I knew it was something small.
Your sorted content and filtered content are both computed, so you need to make sure they are both watching each other for changes. If you bind sortProperties
to filteredContent
, it will work.
property('filterText', '@this', 'sortProperties')
Working JSBin: http://emberjs.jsbin.com/bicepobu/1/edit
I realized that the collection was still alive and no errors were being thrown when I started entering filters into the text field and it was rendering, then I could click twice and bug it out again...
Computed property errors are pretty much the equivalent of the old "forgotten semi-colon". I swear that 9/10 bugs in my own Ember code are from this sort of thing.
Update::
Okay, so I think I can better describe what's happening. You are feeding in the filteredContent
to the macro. That macro is removing and adding items to your filtered content array. If you think about it, what's happening makes sense.
Take a look at this line: https://github.com/emberjs/ember.js/blob/v1.6.1/packages_es6/ember-runtime/lib/computed/reduce_computed_macros.js#L756
return arrayComputed(itemsKey, { //...
filteredContent
, returning a new collection. This is where filteredContent
loses sight!filteredContent
, which was ripped apart and was never updated with the new model! (thus, the need to watch sortedProperties
for changes). It worked the first time because it had a healthy origin array to work from. The second time, it was grabbing at "thin air" (empty array).If your custom filter property isn't watching for changes to sortProperties, it doesn't know to re-establish itself after being mangled in the macro.
Yikes! Certainly don't hold it against the Ember guys.
It would be nice if the sort macro just returned the same collection and not a brand new one... There is probably a really good reason for this.
Upvotes: 4
Reputation: 47367
It looks like Ember, or something else, hates your item controller. My working guess/theory is it disconnects from the item controller at some point, and then all of your sorting and other labels break (due to them being reliant on the item controller)
http://emberjs.jsbin.com/jakax/1/edit
I'm not sure exactly what the issue is, but I'd probably just wrap it in a normal Ember Object (depending on what you're trying to do).
App.Foo = Em.Object.extend({
totalAmount: Em.computed.alias('price.amount'),
symbol: Em.computed.alias('price.currency')
});
http://emberjs.jsbin.com/jakax/2/edit
Upvotes: 2