Created
November 18, 2011 17:10
-
-
Save sbellity/1377079 to your computer and use it in GitHub Desktop.
Knockit = Knockout + Backbone
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
class KnockItObservables | |
constructor: -> | |
@reset({}) | |
make: (ref, attrs)-> | |
return false unless ref && attrs | |
@_viewModels[ref] ?= ko.mapping.fromJS(attrs) | |
@_viewModels[ref].ref = ref | |
@_viewModels[ref] | |
change: (ref, attrs)-> | |
return unless @_viewModels[ref] | |
ko.mapping.fromJS(attrs, @_viewModels[ref]) | |
get: (ref)-> | |
return unless ref | |
@_viewModels[ref] | |
remove: (ref)-> | |
delete @_viewModels[ref] | |
reset: (vals={})-> | |
@_viewModels = vals | |
collectionEventCallbacks = | |
# All those methods are called in the context of the collection... | |
# so, @ = collection here | |
add: (model, collection, options)-> | |
ret = @_knockit.make(model.cid, model.attributes) | |
obs = @getObservable() | |
index = @indexOf(model) | |
index = @length if index == -1 | |
obs.models.splice(index, 0, ret) unless _.contains(_.pluck(obs.models(), "ref"), ret.ref) | |
ret | |
remove: (model, collection, options)-> | |
@getObservable().models.remove(@_knockit.get(model.cid)) | |
@_knockit.remove(model.cid) | |
change: (model, options)-> | |
obs = @_knockit.change(model.cid, model.changedAttributes()) | |
reset: (collection, options)-> | |
obs = @_knockit._viewModels.me | |
@_knockit.reset({ me: obs }) | |
obs.models.removeAll() | |
for m in @models | |
ret = @_knockit.make(m.cid, m.attributes) | |
obs.models.push ret unless _.contains(_.pluck(obs.models(), "ref"), ret.ref) | |
method_missing: (eventName)-> | |
()-> | |
console.warn("No handler defined for #{eventName}, with: ", arguments) | |
onCollectionEvent = ()-> | |
eventName = Array.prototype.shift.call arguments, 1 | |
cb = collectionEventCallbacks[eventName] || collectionEventCallbacks.method_missing(eventName) | |
cb?.apply(this, arguments) | |
class Backbone.ObservableCollection extends Backbone.Collection | |
getObservable: ()-> | |
@_knockit ?= new KnockItObservables | |
unless ret = @_knockit.get("me") | |
@bind "all", => onCollectionEvent.apply(this, arguments) | |
ret = @_knockit._viewModels["me"] = { models: ko.observableArray([]) } | |
collectionEventCallbacks.reset.apply(this) | |
ret | |
getObservableModel: (cid)-> | |
model = @getByCid(cid) | |
return unless model && model instanceof Backbone.Model | |
@_knockit.get(model.cid) || @_knockit.make(model.cid, model.attributes) | |
Backbone.Model::getObservable = ()-> | |
unless @collection instanceof Backbone.ObservableCollection | |
throw "The model has to be linked to an observable collection to get an Observable" | |
@collection.getObservableModel(@cid) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment