How to filter a Backbone collection on the server

Is there a common pattern for using a Backbone service that filters a collection on the server? I haven't been able to find anything on Google and Stack Overflow search results, which is surprising given the number of basic apps in production.


Suppose I am building a new frontend using Backbone.

On the search screen, I need to pass the following information to the server and return the results that the page is facing.

  • filter criteria
  • sorting criteria
  • results per page
  • page number

The backbone doesn't seem to be very interested in filtering the upload to the server. It expects the server to return the entire list of questions and perform client-side filtering.

My guess is that in order to make this work I need to subclass Collection and override fetch so that instead of always fetching data from the same RESTful url, it passes the above parameters.

I don't want to reinvent the wheel. Am I missing a feature in Backbone that makes this process simpler or easier with existing components? Is there already a well-established pattern for solving this problem?

+3


source to share


2 answers


If you just want to pass the GET parameters in the request, you just have to specify them in the fetch call itself.

collection.fetch( {
  data: {
    sortDir: "ASC",
    totalResults: 100
  }
} );

      



The parameters passed to fetch should translate directly to the jQuery.ajax call and the data property should be automatically parsed. Of course, overriding the fetch method is fine too, especially if you want to standardize parts of the logic.

+3


source


You are correct, creating your own Collection

is the way to go as there are no pagination standards other than OData.

Rather than overriding "fetch", what I usually do in these cases is create the property collection.url

as a function, return the correct URL based on the state of the collection.

However, in order to do the pagination, the server needs to return the total number of elements to you so you can calculate how many pages are based on the X elements on the page. Currently, some APIs use things like HAL or HATEOAS, which are basically HTTP response headers. To get this information, I usually add a listener to the event sync

that fires after any AJAX operation. If you need to notify external components (usually a view) of the number of available items / pages, use an event.

A simple example: your server returns X-ItemTotalCount

in response headers and expects the parameters page

and to be executed in the request items

.

var PagedCollection = Backbone.Collection.extend({
  initialize: function(models,options){
    this.listenTo(this, "sync", this._parseHeaders);
    this.currentPage = 0;
    this.pageSize = 10;
    this.itemCount = 0;
  },
  url: function() {
    return this.baseUrl + "?page=" + this.currentPage + "&items=" + this.pageSize;
  },
  _parseHeaders: function(collection,response){
    var totalItems = response.xhr.getResponseHeader("X-ItemTotalCount");
    if(totalItems){
      this.itemCount = parseInt(totalItems);
      //trigger an event with arguments (collection, totalItems)
      this.trigger("pages:itemcount", this, this.itemCount);
    }
  }
});

var PostCollection = PagedCollection.extend({
  baseUrl: "/posts"
});

      



Note that we are using a different property of our own baseUrl

to make it easier to extend PagedCollection. If you need to add your own initialize

, call a parent prototype like this, or you won't be parsing headers:

PagedCollection.protoype.initialize.apply(this,arguments)

You can even add methods fetchNext

and fetchPrevious

to the collection, where you simply change this.currentPage

and fetch

. Remember to add {reset:true}

as fetch

parameters if you want to replace one page with another instead of adding.

Now, if your backend for the project is consistent, any resource that allows pagination to the server can be exposed using a single PagedCollection based collection on the client, provided the same options / responses are used.

+1


source







All Articles