Reputation: 8428
I'm building a search box that filters through records and looks for any entity that has the specified number in the searchBy category:
MyApp.SearchController = Em.ObjectController.extend({
searchTerm: "",
searchBy: "id",
searchFor: "customer",
results: function(){
if(this.get('searchTerm') !== ""){
var searchObj = {};
searchObj[this.get('searchBy')] = this.get('searchTerm');
var that = this;
return this.store.all(this.get('searchFor'))
.filter(function(entity){
return ('' + entity.get(that.get('searchBy'))).indexOf(that.get('searchTerm')) != -1;
});
} else return [];
}.property('searchTerm', 'searchBy', 'searchFor'),
...
});
However there is a large CPU spike as soon as i hit '1' as it will filter through every record and check each id.
Is there a way to limit the filter so that it only returns the first 10 matches?
Upvotes: 0
Views: 53
Reputation: 47367
There are a few things you can do, first off, throttling/debounce should probably be used here, http://emberjs.com/api/classes/Ember.run.html#method_debounce. Here's an example of debouncing, start typing, it won't start searching until you've stopped typing for at least 500 ms. http://emberjs.jsbin.com/covovaye/2/edit
You don't need to call all
, then filter
, just call filter
and send it a function as the filter. Additionally you can save quite a few calls to get by getting searchBy and searchTerm, then using those variables over and over, instead of calling get over and over.
results: function(){
if(this.get('searchTerm') !== ""){
var searchObj = {},
searchBy = this.get('searchBy'),
searchTerm = this.get('searchTerm');
searchObj[searchBy] = searchTerm;
var that = this;
return this.store.filter(this.get('searchFor'), function(entity){
return ('' + entity.get(searchBy)).indexOf(searchTerm) != -1;
});
} else return [];
}.property('searchTerm', 'searchBy', 'searchFor')
If you really wanted to get the first 10 you could use slice
results: function(){
if(this.get('searchTerm') !== ""){
var searchObj = {},
searchBy = this.get('searchBy'),
searchTerm = this.get('searchTerm');
searchObj[searchBy] = searchTerm;
var that = this;
return this.store.all(this.get('searchFor'))
.toArray()
.slice(0,10)
.filter(function(entity){
return ('' + entity.get(searchBy)).indexOf(searchTerm) != -1;
});
} else return [];
}.property('searchTerm', 'searchBy', 'searchFor')
Upvotes: 1