Created
August 16, 2012 15:47
-
-
Save tgriesser/3371206 to your computer and use it in GitHub Desktop.
backbone model change
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
// Returns a hash of attributes whose current and previous value differ. | |
_changed : function(){ | |
var attr, changes = {}, | |
now = this.attributes, | |
old = this._previousAttributes || {}; | |
var all = _.union(_.keys(now), _.keys(old)); | |
// If the new and current value differ, record the change. | |
for (var i = all.length; i>=0; i--) { | |
attr = all[i]; | |
if (!_.isEqual(now[attr], old[attr]) || (_.has(now, attr) != _.has(old, attr))) { | |
changes[attr] = now[attr]; | |
} | |
} | |
return changes; | |
}, | |
// Set a hash of model attributes on the object, firing `"change"` unless | |
// you choose to silence it. | |
set: function(key, value, options) { | |
var attrs, attr, val | |
now = this.attributes; | |
// Handle both `"key", value` and `{key: value}` -style arguments. | |
if (_.isObject(key) || key == null) { | |
attrs = key; | |
options = value; | |
} else { | |
attrs = {}; | |
attrs[key] = value; | |
} | |
// Extract attributes and options. | |
options || (options = {}); | |
if (!attrs) return this; | |
if (attrs instanceof Model) attrs = attrs.attributes; | |
if (options.unset) for (attr in attrs) attrs[attr] = void 0; | |
// Run validation. | |
if (!this._validate(attrs, options)) return false; | |
// Check for changes of `id`. | |
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; | |
// For each `set` attribute... | |
for (attr in attrs) { | |
delete this._escapedAttributes[attr]; | |
// Update or delete the current value. | |
options.unset ? delete now[attr] : now[attr] = attrs[attr]; | |
} | |
// Fire the `"change"` events. | |
if (!options.silent) this.change(options); | |
return this; | |
}, | |
// Call this method to manually fire a `"change"` event for this model and | |
// a `"change:attribute"` event for each changed attribute. | |
// Calling this will cause all objects observing the model to update. | |
change: function(options) { | |
var change, | |
changed = this._changed(), | |
changing = this._changing; | |
this._changing = true; | |
for (change in changed) { | |
this.trigger('change:' + change, this, changed[change], options || {}); | |
} | |
if (changing) return this; | |
if (!_.isEmpty(changed)) this.trigger('change', this, options); | |
this._changing = false; | |
this._previousAttributes = _.clone(this.attributes); | |
return this; | |
}, | |
// Determine if the model has changed since the last `"change"` event. | |
// If you specify an attribute name, determine if that attribute has changed. | |
hasChanged: function(attr) { | |
var changed = this._changed(); | |
if (attr == null) return !_.isEmpty(changed); | |
return _.has(changed, attr); | |
}, | |
// Return an object containing all the attributes that have changed, or | |
// false if there are no changed attributes. Useful for determining what | |
// parts of a view need to be updated and/or what attributes need to be | |
// persisted to the server. Unset attributes will be set to undefined. | |
// You can also pass an attributes object to diff against the model, | |
// determining if there *would be* a change. | |
changedAttributes: function(diff) { | |
var changed = this._changed(); | |
if (!diff) return !_.isEmpty(changed) ? changed : false; | |
var val, changes = false, old = this._previousAttributes; | |
for (var attr in diff) { | |
if (_.isEqual(old[attr], (val = diff[attr]))) continue; | |
(changes || (changes = {}))[attr] = val; | |
} | |
return changes; | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment