Pagination/Sorting/Filtering for a beginner

I was pretty surprised myself to find that there really is no standard solution for both client-side and server-side pagination in Ember. Originally, my big plan was to use http://datatables.net, but I ran into several issues whenever I needed to update an already-rendered table. DataTables wound up being a very well-written jQuery plugin that’s doing DOM manipulation, but without coordinating with Ember.

So I opted to roll my own. It actually came out really nicely, and it’s trivially easy for me to add server-side or client-side pagination (I can choose by selecting the right Mixin) on any page. If I had more free time, I would dress it up and release as open source, but in the meantime here are some tips that may help you out. Feel free to message me or post here with any specific questions.

Structure
I decided to create three Mixins for my paginator:

  • PaginatorBaseMixin
  • PaginatorClientSideMixin
  • PaginatorServerSideMixin

The baseMixin defines a common set of properties and computed properties that both the client-side and server-side paginator will need. These include: searchString, sortBy, isSortAscending, totalItems, itemsPerPage, etc. The computed properties were things like nextPage, prevPage, itemLowerBound, itemUpperBound, and availablePages.

That last one, availablePages is responsible for deciding which pages at the bottom of the screen to render, like 1…4, 5, 6, 7 … 19. That turned out to be kind of a funny algorithm but it works nice now.

In the individual serverSideMixin or clientSideMixin, the main differences are how nextPageClick is handled (do we reload from server, or simply update the currentPage property), and how to get the content itself.

In the serverSideMixin, as you discovered, query_params are an ideal fit here. Ultimately, each time you sort a column or advance a page, or really do anything, thanks to query params, Ember re-queries the server and gets fresh data.

To answer your question about local storage for serverSidePaginator, the key issue here is that Ember is only getting a subset of your full data. Let’s say your actual data set has 1,000,000 rows. Because Ember doesn’t have the full data set, it can’t handle any sorting locally. And even page advancing should trigger the served b/c maybe there’s new data since we last checked?

For the ClientSidePaginator, I just download all the content upfront in my model: handler in the route, and use a computed property that wraps this that does nothing more than slice the content from index 1 to index 10, or whatever page you’re on.

I know this was a bit of a ramble, but hopefully has some helpful tidbits.

5 Likes