src/components/collection_view.coffee in luca-0.9.4 vs src/components/collection_view.coffee in luca-0.9.6
- old
+ new
@@ -1,18 +1,36 @@
-# Public: The CollectionView renders a collection of models into a list of items.
+collectionView = Luca.define "Luca.components.CollectionView"
+# The CollectionView facilitates the rendering of a Collection
+# of models into a group of many rendered templates
#
-# Examples
+# Example:
#
-# _.def('App.ListView').extends('Luca.components.CollectionView').with
-# collection: new App.SampleCollection()
-# itemTemplate: "list_view_item"
-# loadMask: true
+# new Luca.components.CollectionView
+# itemTemplate: "template_name"
+# collection: "collection_class_name"
+# pagination:
+# page: 1
+# limit: 15
+# filterable:
+# query:
+# default: 'value'
#
+collectionView.extends "Luca.components.Panel"
-_.def("Luca.components.CollectionView").extends("Luca.components.Panel").with
- tagName: "div"
+collectionView.behavesAs "LoadMaskable",
+ "Filterable",
+ "Paginatable"
+collectionView.triggers "before:refresh",
+ "after:refresh",
+ "refresh",
+ "empty:results"
+
+collectionView.defaults
+
+ tagName: "ol"
+
className: "luca-ui-collection-view"
bodyClassName: "collection-ui-panel"
# A collection view can pass a model through to a template
@@ -23,81 +41,133 @@
itemTagName: 'li'
itemClassName: 'collection-item'
- hooks:[
- "empty:results"
- ]
-
initialize: (@options={})->
_.extend(@, @options)
_.bindAll @, "refresh"
unless @collection? or @options.collection
+ console.log "Error on initialize of collection view", @
throw "Collection Views must specify a collection"
unless @itemTemplate? || @itemRenderer? || @itemProperty?
throw "Collection Views must specify an item template or item renderer function"
Luca.components.Panel::initialize.apply(@, arguments)
if _.isString(@collection) and Luca.CollectionManager.get()
@collection = Luca.CollectionManager.get().getOrCreate(@collection)
- if Luca.isBackboneCollection(@collection)
+ unless Luca.isBackboneCollection(@collection)
+ throw "Collection Views must have a valid backbone collection"
+
@collection.on "before:fetch", ()=>
- @trigger "enable:loadmask" if @loadMask is true
+ @trigger "enable:loadmask"
@collection.bind "reset", ()=>
- @trigger "disable:loadmask" if @loadMask is true
@refresh()
+ @trigger "disable:loadmask"
- @collection.bind "add", @refresh
- @collection.bind "remove", @refresh
- else
- throw "Collection Views must have a valid backbone collection"
+ @collection.bind "remove", ()=>
+ @refresh()
- if @collection.length > 0
- @refresh()
+ @collection.bind "add", ()=>
+ @refresh()
- attributesForItem: (item)->
- _.extend {}, class: @itemClassName, "data-index": item.index
+ if @observeChanges is true
+ @collection.on "change", @refreshModel, @
+ unless @autoRefreshOnModelsPresent is false
+ @defer ()=>
+ @refresh() if @collection.length > 0
+ .until("after:render")
+
+ @on "collection:change", @refresh, @
+
+ attributesForItem: (item, model)->
+ _.extend {}, class: @itemClassName, "data-index": item.index, "data-model-id": item.model.get('id')
+
contentForItem: (item={})->
if @itemTemplate? and templateFn = Luca.template(@itemTemplate)
- content = templateFn.call(@, item)
+ return content = templateFn.call(@, item)
if @itemRenderer? and _.isFunction( @itemRenderer )
- content = @itemRenderer.call(@, item, item.model, item.index)
+ return content = @itemRenderer.call(@, item, item.model, item.index)
- if @itemProperty
- content = item.model.get(@itemProperty) || item.model[ @itemProperty ]
- content = content() if _.isFunction(content)
+ if @itemProperty and item.model?
+ return content = item.model.read( @itemProperty )
- content
+ ""
makeItem: (model, index)->
item = if @prepareItem? then @prepareItem.call(@, model, index) else (model:model, index: index)
- make(@itemTagName, @attributesForItem(item), @contentForItem(item))
+ attributes = @attributesForItem(item, model)
+ content = @contentForItem(item)
+ # TEMP
+ # Figure out why calls to make are failing with an unexpected string error
+ try
+ make(@itemTagName, attributes, content)
+ catch e
+ console.log "Error generating DOM element for CollectionView", @, model, index
+ #no op
- getModels: ()->
- if @collection?.query and (@filter || @filterOptions)
- @collection.query(@filter, @filterOptions)
+ getCollection: ()->
+ @collection
+
+ # Private: returns the query that is applied to the underlying collection.
+ # accepts the same options as Luca.Collection.query's initial query option.
+ getQuery: ()->
+ @query ||= {}
+
+ # Private: returns the query that is applied to the underlying collection.
+ # accepts the same options as Luca.Collection.query's initial query option.
+ getQueryOptions: ()->
+ @queryOptions ||= {}
+
+ # Private: returns the models to be rendered. If the underlying collection
+ # responds to @query() then it will use that interface.
+ getModels: (query,options)->
+ if @collection?.query
+ query ||= @getQuery()
+ options ||= @getQueryOptions()
+
+ @collection.query(query, options)
else
@collection.models
- refresh: ()->
+ locateItemElement: (id)->
+ @$(".#{ @itemClassName }[data-model-id='#{ id }']")
+
+ refreshModel: (model)->
+ index = @collection.indexOf( model )
+ @locateItemElement(model.get('id')).empty().append( @contentForItem({model,index}, model) )
+ @trigger("model:refreshed", index, model)
+
+ refresh: (query,options)->
+ query ||= @getQuery()
+ options ||= @getQueryOptions()
+
@$bodyEl().empty()
+ models = @getModels(query, options)
- if @getModels().length is 0
+ @trigger("before:refresh", models, query, options)
+
+ if models.length is 0
@trigger("empty:results")
- _( @getModels() ).each (model, index)=>
- @$append( @makeItem(model, index) )
+ index = 0
+ for model in models
+ @$append @makeItem(model, index++)
+
+ @trigger("after:refresh", models, query, options)
+
+ @
+
registerEvent: (domEvent, selector, handler)->
if !handler? and _.isFunction(selector)
handler = selector
selector = undefined
@@ -108,7 +178,8 @@
@refresh()
@$attach() if @$el.parent().length > 0 and @container?
@
# Private Helpers
+
make = Luca.View::make