Skip to content

Commit

Permalink
fixes, changes, updated readme for revert brach
Browse files Browse the repository at this point in the history
  • Loading branch information
drewlesueur committed Dec 17, 2010
1 parent cd34839 commit 952814a
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 171 deletions.
19 changes: 13 additions & 6 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ It gives some methods for helping you create JavaScript web applications.

## Diferences from backbone.js

* One class for everything. A single class handles a model and a collection
* There is no extra view. The `append`, and `render` methods of the model are essentially the view.
`append` is for when the model is created--how it gets appended to the dom. `render` is usually for when the model is updated.
* binding and trigger are per-class instead of per-object. You just have the `triggers` property on
the class. It is just an hash of the triggers. You don't have to manually bind.
* Models can be fully nested. This can be helpful for storing to a mongodb backend.
* The main difference is Neckbrace uses real javascript objects and arrays, not nested ones
* Functions are called based off the __cid of the object or array.
* neckbrace models have meta elements like `_m(obj).el`
* call polymorphic functions like `_t(obj).myfunction()`
this will look up the type of the meta object of `obj` (like `_m(ojb).type.myFunction o`)
* Copied this way of doing oop from Underscore.js

Still working out kinks

##Thoughts.
people.phones[0].extension
peopele.get("phones").get(1).get("extension")
people.attributes.phones.collection[0].extension
listing._.save()
_t(record).save()
176 changes: 66 additions & 110 deletions neckbrace.coffee
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
# people.phones[0].extension
# peopele.get("phones").get(1).get("extension")
# people.attributes.phones.collection[0].extension
#listing._.save()
Neckbrace = window.Neckbrace = {};
Neckbrace.emulateJSON = true
Neckbrace.emulateHTTP = true
#later instead of doing this on underscore, do it on another object

makeLikeUnderscore = () ->
_nb = (o) ->
_nb.currentObject = o
Expand All @@ -15,142 +6,108 @@ makeLikeUnderscore = () ->
_nb.mixin = (funcs) ->
for name, func of funcs
_nb[name] = func
_nb.methods[name] = (args...) ->
func(_nb.currentObject, args...)
return _nb
_nb.methods[name] = (args...) -> func(_nb.currentObject, args...)
return _nb
_nb = window._nb = makeLikeUnderscore()
_nb.emulateJSON = _nb.emulateHTTP = true
_nb = window._nb = makeLikeUnderscore()
_nb.currentUniqueId = 0
_nb.metaInfo = {}
_nb.mixin
uniqueId: () ->
_nb.currentUniqueId +=1
extend: (model, params) ->
ret = _.clone model
_.extend ret, params
ret.super = model
ret
extendModel: (params) -> _.extend _nb.Model, params
extendCollection: (params) -> _.extend _nb.Collection, params
uniqueId: () -> _nb.currentUniqueId +=1
metaObj: (o, extra) -> #can be array
cid = _nb.uniqueId()
o.__cid = cid
metaO = _nb.metaInfo[cid] =
record: o
metaO = _nb.metaInfo[cid] = record: o
_.extend metaO, extra
if metaO.type and metaO.type.initialize
_nb(o).initialize()
if metaO.type and metaO.type.initialize then _nb(o).initialize()
o
metaType: (type, o) ->
_nb.metaObj o, {type: type}
metaType: (type, o) -> _nb.metaObj o, {type: type}
meta: (o) ->
meta = _nb.metaInfo[o.__cid]
return meta
save: (o, args...) ->
_nb.meta(o).type.save o, args...
meta
_m = window._m = (o) -> _nb(o).meta()
#t is for types
_t = window._t = makeLikeUnderscore()
_t = window._t = makeLikeUnderscore() #t is for types
_t.addMethods = (methodNames) ->
mixins = {}
for name in methodNames
mixins[name] = (o, args...) ->
_m(o).type[name] o, args...
_t.mixin mixins
_t.addMethods ["save", "initialize", "append", "render", "add", "remove", "fetch"
"getById", "getByCid", "toJSON", "set", "isNew", "appendingEl", "url"]
#metaMethods = ["save", "initialize", "append", "render", "add", "remove", "fetch"
#"getById", "getByCid", "toJSON", "set", "isNew", "appendingEl", "url"]
#mixins = {}
#for method in metaMethods
# mixins[method] = (o, args...) ->
# _.meta(o).type[method] o, args...
#_.mixin mixins
#_t = (o) -> _m(o).type......
Neckbrace.Model =
appendingEl: (o) ->
return _m(o).el
#triggers:
# "change:id": () -> #"add", "change", "remove"
# console.log this.id + "was triggered"
mixins[name] = (o, args...) -> _m(o).type[name] o, args...
_t.mixin mixins
_t.addProps = (propNames) -> #static attributes
mixins = {}
for name in propNames
mixins[name] = (o) -> _m(o).type[name]
_t.mixin mixins
_t.addMethods ["save", "initialize", "append", "render", "add", "remove", "fetch", "getById", "getByCid", "toJSON", "set", "isNew", "appendingEl", "url"]
_t.addProps ["triggers"]
_nb.Model =
appendingEl: (o) -> return _m(o).el
#triggers: {"change:id": () -> console.log this.id + "was triggered"}
initialize: (o, params) ->
_(o).meta "cid" : _.uniqueId() #kind of redundant
_m(o).element = "div"
_.append o
_.render o
mo = _m(o)
mo.cid = _.uniqueId() #kind of redundant
mo.element = "div"
_.append o and _.render o
append: (o) ->
if not (_m(o).el) then _m(o).el = document.createElement _nb(o).meta.element
if _m(o).parent
appendingEl = _.appendingEl _m(o).parent
$(appendingEl).append _m(o).el
mo = _m(o)
if not (mo.el) then mo.el = document.createElement mo.element
if mo.parent
$(_t(mo.parent).appendingEl()).append mo.el
else
$(document.body).append _m(o).el
render: (o) ->
$(_m(o).el).attr "data-neckbrace", "true"
#$(_m(o).el).bind("click", () -> )
toJSON: (o) -> #todo: make sure nesting works
return o
$(document.body).append mo.el
render: (o) -> #specific rendering
toJSON: (o) -> return o #this is the beaty of using meta stuff
ajax: $.ajax
url: (o) -> "/neckbraces"
isNew: (o) ->
if o.id or o._id #also this.id or this._id
return false
return true
isNew: (o) -> return (o.id or o._id)
save: (o, options) ->
method = if _t(o).isNew() then "create" else "update"
Neckbrace.sync method, this, options.success, options.error
fetch: (o, options) ->
#todo: add more options, fetch single or fetch many
Neckbrace.sync "read", o, options.success, options.error
delete: (o, options) ->
Neckbrace.sync "delete", o, options.success, options.error
_nb.sync method, this, options.success, options.error
fetch: (o, options) -> _nb.sync "read", o, options.success, options.error #todo add more hre
delete: (o, options) -> _nb.sync "delete", o, options.success, options.error
set: (o, vals) ->
mo = _m(o)
mo = _m(o) and tp = mo.type
for key, val of vals
old = o[key]
o[key] = val
if _m(o).triggers["change:#{key}"]
mo.triggers["change:#{key}"].apply(o, [old])
if mo.triggers["chage"]
mo.triggers["change"].apply(o)
get: (o, val) ->
return o[val]
Neckbrace.Collection = _.clone Neckbrace.Model
_.extend Neckbrace.Collection,
old = o[key] and o[key] = val
if tp.triggers["change:#{key}"] then tp.triggers["change:#{key}"].apply(o, [old])
if tp.triggers["chage"] then tp.triggers["change"].apply(o)
get: (o, val) -> return o[val]
_nb.Collection = _nb.extendModel
add: (o, adding) ->
mo = _m(o)
if not("_byId" of mo)
mo._byId = {}
if not("_byUid" of mo)
mo._byUid = {}
mo = _m(o) and tp = mo.type
if not("_byId" of mo) then mo._byId = {}
if not("_byUid" of mo) then mo._byUid = {}
#this emulates backbone collections
o.push adding
if "id" of adding
mo._byId[adding.id] = adding
else if "_id" of adding
mo._byId[adding._id] = adding
if "cid" of adding
mo._byCid[adding.cid] = adding
if "cid" of adding then mo._byCid[adding.cid] = adding
_m(adding).parent = o
if mo.triggers["add"]
mo.triggers["add"].apply(o)
if tp.triggers["add"] then tp.triggers["add"].apply(o)
remove: (model) ->
_mo = _m(o)
mo = _m(o) and tp = mo.type
model = mo.getByCid(model) || mo.get(model)
if not model then return null
delete mo._byId[model.id]
delete mo._byCid[model.cid]
delete model.parent #backbone says model.collection
o.splice _.indexOf(o, model), 1
if mo.triggers["remove"]
mo.triggers["remove"].apply(this)
getById: (o, id) ->
_m(o)._byId[id]
getByCid: (o, cid) ->
_m(o)._byCid[cid]
#giving neckbrace.type the underscore methods

Neckbrace.sync = (method, o, success, error) -> #copied from Backbone.sync
if tp.triggers["remove"] then tp.triggers["remove"].apply(this)
getById: (o, id) -> _m(o)._byId[id]
getByCid: (o, cid) -> _m(o)._byCid[cid]
_nb.sync = (method, o, success, error) -> #copied from Backbone.sync
mo = _m(o)
if method in ['create', 'update']
modelJSON = JSON.stringify _t(o).toJSON()
method_map =
'create' : "POST"
'update' : 'PUT'
'delete' : "DELETE"
'read' : 'GET'
if method in ['create', 'update'] then modelJSON = JSON.stringify _t(o).toJSON()
method_map = {'create' : "POST", 'update' : 'PUT', 'delete' : "DELETE", 'read' : 'GET'}
type = method_map[method]
params =
url: _t(o).url()
Expand All @@ -161,14 +118,13 @@ Neckbrace.sync = (method, o, success, error) -> #copied from Backbone.sync
processData: false
success: success
error: error
if Neckbrace.emulateJSON
if _nb.emulateJSON
params.contentType = 'application/x-www-form-urlencoded'
params.processData = true
params.data = if modelJSON then {model: modelJSON} else {}
if Neckbrace.emulateHTTP
if _nb.emulateHTTP
if type is 'PUT' or type is 'DELETE'
if Neckbrace.emulateJSON then params.data._method = type
if _nb.emulateJSON then params.data._method = type
params.type = 'POST'
params.beforeSend = (xhr) ->
xhr.setRequestHeader "X-HTTP-Method-Override", type
params.beforeSend = (xhr) -> xhr.setRequestHeader "X-HTTP-Method-Override", type
o.ajax params
Loading

0 comments on commit 952814a

Please sign in to comment.