coderatchet
coderatchet

Reputation: 8428

Emberjs: Paginating Fixture Data

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

Answers (1)

Kingpin2k
Kingpin2k

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

Related Questions