JoeFrizz
JoeFrizz

Reputation: 711

Pagination with collection.fetch() in backbone.marionette

I am trying to implement pagination with backbone.marionette's compositeView by first doing an initial fetch:

collection.fetch({reset: true})

To load additional models into the same collection,

collection.fetch({reset: false, remove: false})

is used.

I saw that on each use of fetch() with {reset: false} muliple add events are triggered (for every model added.) Thats fine basically, but when looking into the annotated source of the compositeView's appendHtml function in marionette the follwing statement is given:

buffering happens on reset events and initial renders in order to reduce the number of inserts into the document, which are expensive.

While this is great for the initial fetch (only 1 browser reflow), every subsequent fetch with {reset: false} could get pretty expensive (reflow on every single model thats added). It really seems to append() the itemView every single time - causing a reflow (compositeView.isBuffering is false).

Is there any way to "batch" process the models and do a single insert (same as done on the reset event)?

Does this need an overwrite in the appendHtml implementation and implement the batch logic by myself?

Upvotes: 1

Views: 2662

Answers (1)

David Sulc
David Sulc

Reputation: 25994

(I assume you don't want to use Backbone.paginator, for some reason. If that isn't the case, use the plugin ;-D).

You could use a technique similar to the filtered collection used here: https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/entities/common.js#L2 (instanciation at https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/apps/contacts/list/list_controller.js#L13).

Basically: you provide a "paginated collection" to the view, and what the paginated collection does is:

  • initially, return a "cloned" copy of the original collection
  • when you fetch on the original collection, add the fetched events in "batch" to the cloned collection, which will trigger the view to refresh (because it's listening to the cloned collection, not the original)

To minimize reflows, you can try the following:

  • silence the events that the collection listens to ("add", etc.)
  • when a group of models gets added, create a new instance of a collection view with only the new models
  • render the new collection view (but don't show it anywhere), and manually append the newView.el to the right place in the DOM
  • destroy the newView

Unfortunately, once you need to start optimizing, you tend to need to handle a bunch of things by hand...

Upvotes: 2

Related Questions