Created
January 15, 2012 22:02
-
-
Save pavanpodila/1617641 to your computer and use it in GitHub Desktop.
A CollectionView class that monitors Backbone.Collections and renders the item Views
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define -> | |
# The CollectionView class provides a simple view manager for a Backbone Collection. | |
# It listens to changes on the collection and reflects that on the view. It also provides | |
# view filtering, grouping and sorting capabilities. | |
class CollectionView extends Backbone.View | |
initialize: (options)-> | |
throw "collection property must be specified." if not @collection | |
@_ready = $.Deferred() | |
@_pendingCount = 0 | |
@_byModelId = {} | |
@createView = options.createView | |
@renderItemView = options.renderItemView or @defaultRenderItemView | |
# listen to collection changes | |
@collection.bind 'add', @addItem, @ | |
@collection.bind 'remove', @removeItem, @ | |
@collection.bind 'reset', @resetItems, @ | |
addItem:(model)-> | |
@renderItem(model) | |
removeItem:(model)-> | |
view = @_byModelId[model.cid] | |
delete @_byModelId[model.cid] | |
view?.remove() | |
resetItems:(models)-> | |
view.remove() for cid, view of @_byModelId | |
@_byModelId = {} | |
getByModelId:(modelId)-> | |
return @_byModelId[modelId] | |
views:-> | |
(view for key, view of @_byModelId) | |
hasItem:(item)-> | |
!!@_byModelId[item.model.cid] | |
defaultRenderItemView:(view)-> | |
view.render() | |
@el.append view.el | |
view.postRender?() | |
renderItem:(model, customRender)-> | |
view = @createView model | |
@_byModelId[model.cid] = view | |
(customRender or @renderItemView).call @, view | |
render: (options) -> | |
{defer} = options or { defer: true } | |
@_pendingCount = @collection.length | |
@collection.each (item) => | |
fn = => | |
@renderItem item | |
@_pendingCount-- | |
@_ready.resolve() if not @_ready.isResolved() and @_pendingCount is 0 | |
if defer then (_.defer => fn()) else fn() | |
remove:-> | |
view.remove() for cid, view of @_byModelId | |
#----------- Filtering, Grouping and Sorting -------------------# | |
applyOperations:(config)-> | |
config = _.extend { sortFn:(->true), groupFn:(->true), complete:(->) }, config | |
@_ready.done => | |
groups = _.groupBy @collection.models, config.groupFn | |
for key, items of groups | |
sortedItems = _.sortBy items, config.sortFn | |
groups[key] = sortedItems | |
# Collect the views | |
groupedViews = {} | |
for key, items of groups | |
itemViews = (@getByModelId(item.cid) for item in items) | |
groupedViews[key] = itemViews | |
config.complete groupedViews | |
filter:(config) -> | |
config = _.extend { predicate:(->true), complete:(->) }, config | |
@_ready.done => | |
filtered = _.filter @collection.models, (item) -> config.predicate(item) | |
filteredViews = (@getByModelId(item.cid) for item in filtered) | |
config.complete filteredViews |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment