Created
October 13, 2011 17:55
-
-
Save thejefflarson/1284940 to your computer and use it in GitHub Desktop.
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
// The primary function of a **Model** is to manipulate and query data. For example filtering | |
// an array-type object should happen in a subclass of Model. Another great candidate | |
// for a **Model** is any object that requires an external resource such as an ajax call. | |
// | |
// Basically, any long running or long blocking operation should happen in a model. | |
// | |
// **Models** are bindable as well, so you can subscribe to notifications by calling | |
// `bind` with a callback and an event to subscribe to recieve events from another object. | |
// | |
// **Models** are usually encapsulated in **Views** and rarely, if ever, stand alone. | |
// | |
propublica.Model = Base.extend({ | |
// The **init** method copies the passed in attributes to the instance's built in | |
// **_attrs** object. | |
MODEL_CHANGED : "changed", | |
init : function(attrs){ | |
this._attrs = this._attrs || {}; | |
_.extend(this._attrs, attrs); | |
if('id' in this._attrs) this.id = attrs.id; | |
this.cid = _.uniqueId(this.name || this.id || ""); | |
}, | |
// Access an attribute by key. | |
read : function(key){ | |
return this._attrs[key]; | |
}, | |
// Set an attribute by key. Pass in an object for key to assign multiple values. | |
write : function(key, attr){ | |
attrs = {}; | |
!_.isUndefined(attr) ? attrs[key] = attr : attrs = _.extend(attrs, key); | |
for(var k in attrs){ | |
var value = attrs[k]; | |
var old = this._attrs[k]; | |
if('id' in attrs) this.id = attrs.id; | |
if (!_.isEqual(old, value)) { | |
this._attrs[k] = value; | |
this._onchange(k, old, value); | |
} | |
} | |
return this; | |
}, | |
// delete an attribute by key. | |
remove : function(key){ | |
var oldAttr = this._attrs[key]; | |
delete this._attrs[key]; | |
this._onchange(key, oldAttr, undefined); | |
return oldAttr; | |
}, | |
_onchange : function(key, old, value){ | |
this.fire(this.MODEL_CHANGED, this, key, old, value); | |
this.fire(this.keyPath(key), this, key, old, value); | |
}, | |
keyPath : function(key){ | |
return [key, this.MODEL_CHANGED].join("_"); | |
}, | |
bind : function(e, cb){ | |
var callbacks = (this._callbacks = this._callbacks || {}); | |
var list = (callbacks[e] = callbacks[e] || []); | |
list.push(cb); | |
}, | |
unbind : function(e, cb){ | |
if(!(this._callbacks && this._callbacks[e])) return; | |
var list = this._callbacks[e]; | |
for(var i = 0; i < list.length; i++){ | |
if(list[i] === cb) { | |
list.splice(i, 1); | |
break; | |
} | |
} | |
}, | |
unbindAll : function(){ | |
delete this._callbacks; | |
}, | |
fire : function(e){ | |
if(!this._callbacks) return; | |
var list = this._callbacks[e]; | |
if(!list) return; | |
for(var i = 0; i < list.length; i++) list[i].apply(this, arguments); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment