Backbone Marionette Filtered Collection Views

Backbone.Marionette is probably the best thing that ever happened to Backbone.

What is Backbone.js?

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

What is Backbone.Marionette?

Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications. It is a collection of common design and implementation patterns found in the applications that I (Derick Bailey) have been building with Backbone, and includes various pieces inspired by composite application architectures, such as Microsoft’s “Prism” framework.

The need for filtered collections

Let’s say I have a collection A that can be updated dynamically both client-side and server-side (items added, removed, resorted). Let’s ViewA be a CollectionView

ListView = new Marionette.CollectionView({collection: A});

Elements of A have an attribute is_starred. I’d like to provide a filter option in the UI that will cause ListView to show only starred elements of A. I know the general pattern of filtering A on the is_starred property to create a new collection AStarred and pass it to ListView. The problem is that when items are added or deleted to A, I also need them to be added/deleted to AStarred if they’re starred.

What’s a good approach to achieve this?

One approach is to create a custom collection StarredCollection that is initialized using A and listens on add/remove/reset events on A, and only adds/removes items that are starred, and then pass an instance of StarredCollection to ViewA.

Another approach is to create a custom view, StarredView, with wrappers around addItemView/removeItemView that only calls the corresponding methods in the CollectionView if the item passes a test. This could even be generalized to FilteredCollectionView where a filter is parameter, so one could filter on whatever.

I went with the second approach.

Here is how I did it.

First, patch Marionette’s CollectionView (I could’ve created a SortedCollectionView instead, but this was easier in my case).

Then, say I have CollectionView called ListView, and I want to create a filtered version of it:

Or, if I’m showing the ListView in a Layout’s regions, then I create StarredLayout:

But I also modified on the ListLayout.onRender to pass the filter to the list view before creating the ListView:

Warning: this breaks the handling of EmptyView which will be shown only when the original collection is empty, not when filtered collection is empty.

I hope others find this useful and suggest ways of improving it.

One thought on “Backbone Marionette Filtered Collection Views

  1. sydney

    This works nicely for me, but I would love to see more code context. For instance, I am unclear on what you mean by this: “But I also modified on the ListLayout.onRender to pass the filter to the list view before creating the ListView:” The code provided seems to refer to a static collection? TitanFile.channelList.

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *