Collection.coffeesrc/ | |
---|---|
Provides a simple collection class, which can be used to handle retrieval and management of sets of Models | define ['require', './Api', './Events'], (require, Api, Events) -> \
new Class |
Extends the native javascript Array object so we get all the methods of this class as well as the Mootools extensions. | Extends: Array |
Uses Api for collection retrieval | Implements: [Options, Events, Api]
options: {} |
If using a custom Model then it needs to set here, as this class will
be used to create new instances after calling | |
If using default | url: null |
Using the Collection class | |
You can initialise the collection with a set of existing models, e.g. if you bootstrap. If you want to set | initialize: (models=[], options={}) ->
if options.parentModel?
@parentModel =
id: options.parentModel.id
klass: options.parentModel.constructor |
Can't store actual instance otherwise browswers crash in some instances presumabley down to a circular reference | delete options.parentModel
for key in ['model', 'url', 'sortField']
if options[key]?
@[key] = options[key]
delete options[key]
@setOptions options
if not @model
@model = require 'bags/Model'
@add models, silent: true
@ |
Collection retrievalThe actual collection api has been abstracted out to Api which should be read to learn about the various events fired during each operation and as well as how to handle to returned promise. | |
Use this method to fetch a collectin of models from the server. By default this will replace the current collection with the retrieved
collection by calling If you wish to add to the collection rather than replace it then set
| fetch: (filter={}, options={}) ->
promise = @api 'list', filter
promise.then (models) =>
if options.add
@add models, options
else
@reset models, options
@fireEvent 'fetch', [true] unless options.silent
return this |
This will replace the current collection with the models that are passed
in, and fires a If you call this without any options it will just empty the collection. | reset: (models, options={}) ->
@_remove model, options while model = @pop()
@add models, silent: true if models?
@fireEvent 'reset', [@] unless options.silent |
Call to add a model or an array of models to the collection
Fires an | add: (model, options={}) ->
if not @model? then throw new Error "Model not defined for collection"
if typeOf(model) == 'array'
added = @_add(m, options) for m in model
else
added = @_add model, options
@sortBy @sortField, silent: true if @sortField?
unless options.silent
@fireEvent 'add', [model] for model in Array.from added
_add: (model, options={}) ->
model = @_makeModel model
@push model
model |
Provides a shortcut to create a new model in the collection | create: (attributes, options={}) ->
model = @_makeModel attributes
@add model, options
return model |
Get model with field matching value | get: (field, value) ->
for obj in this
return obj if obj.get(field) == value |
Sorts the collection like a normal array but also fires a | sort: (comparator=@comparator, options={}) ->
@parent comparator
@fireEvent 'sort' unless options.silent
_parseSort: (field) ->
if field.substr(0,1) is '-'
[field.substr(1), true]
else
[field, false]
sortBy: (field, options) ->
[field, descending] = @_parseSort(field)
@sort (a, b ) ->
if descending
bVal = a.get field
aVal = b.get field
else
aVal = a.get field
bVal = b.get field
type = typeOf aVal
if type == 'number'
aVal - bVal
else if type == 'string'
aVal.toLowerCase().localeCompare bVal.toLowerCase()
else if type == 'date'
bVal.diff aVal, 'ms'
, options
sortField: null |
Set this to define a custom comparator for the | comparator: (a, b) ->
return a - b |
Returns a JSON ready representation of the Collection. See Model for more information. | toJSON: ->
@invoke 'toJSON' |
Private methods | _makeModel: (model) ->
if not instanceOf model, @model
model = new @model model, collection: this
else if not model.collection?
model.collection = this
model.addEvents
any: =>
@_modelEvent model, arguments
destroy: =>
index = @indexOf model
@erase model
@fireEvent 'remove', [model, index]
model
_modelEvent: (model, args) ->
@fireEvent args[0], [model, args[1]]
_remove: (model, options={}) ->
model.removeEvents 'any'
model.removeEvents 'destroy'
@erase model
@fireEvent 'remove', [model] unless options.silent
isCollection: true
|