backbone-publication
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -84,2 +84,34 @@ import _ from 'underscore'; | ||
return _.isObject(obj) && !_.isArray(obj); | ||
}, | ||
/** | ||
* Performs a deep clone of an object. | ||
* @param {Object} source - the object to clone. | ||
* @returns {Object} a clone of the given object, where any descendent objects are themselves | ||
* cloned, and not just references to their respective counterpart in `source`. | ||
*/ | ||
deepClone: function deepClone(source) { | ||
var clone = _.clone(source); | ||
_.each(clone, function (v, k) { | ||
if (_.isObject(v)) { | ||
clone[k] = ObjectUtils.deepClone(v); | ||
} | ||
}); | ||
return clone; | ||
}, | ||
/** | ||
* Returns the changes between two objects. Includes attributes in `b` that are not in `a`, and | ||
* attributes that are in both `a` and `b` but where the values differ. Performs deep comparison | ||
* of objects and arrays. | ||
* @param {Object} a - the source object. | ||
* @param {Object} b - the comparison object. | ||
* @returns {Object} an object containing the attributes of `b` which differ from `a`. | ||
*/ | ||
changes: function changes(a, b) { | ||
var toReturn = {}; | ||
_.each(b, function (v, k) { | ||
if (!_.has(a, k) || !_.isEqual(a[k], v)) toReturn[k] = v; | ||
}); | ||
return toReturn; | ||
} | ||
@@ -163,10 +195,24 @@ }; | ||
var oldAttributes = _.omit(this.attributes, '_id', 'createdAt'); | ||
var fullAttributes = ObjectUtils.deepExtend(oldAttributes, newAttributes); | ||
var fullAttributes = ObjectUtils.deepExtend(ObjectUtils.deepClone(oldAttributes), newAttributes); | ||
// Perform the standard Backbone.js set. Do this first, so when we trigger | ||
// events further down the new attributes are in place. | ||
/* Determine which attributes actually changed. This protects against things like the existing | ||
* value for an attribute being passed in. */ | ||
var changedAttributes = ObjectUtils.changes(oldAttributes, fullAttributes); | ||
// If there were no real changes, we can bail. | ||
var hasChanges = !_.isEmpty(changedAttributes); | ||
if (!hasChanges) return; | ||
/* Perform the standard Backbone.js set. Do this first, so when we trigger events further down | ||
* the new attributes are in place. We also determine if all the changes were to nested | ||
* objects - if so, we don't emit any events (but still call `set` so the new attributes are | ||
* stored on the model). */ | ||
var allChangesAreObjects = _.every(changedAttributes, function (v) { | ||
return _.isObject(v); | ||
}); | ||
var standardOpts = _.extend({}, options, { silent: allChangesAreObjects }); | ||
if (options.unset) { | ||
PublicationModel.__super__.unset.call(this, fullAttributes, options); | ||
PublicationModel.__super__.unset.call(this, changedAttributes, standardOpts); | ||
} else { | ||
PublicationModel.__super__.set.call(this, fullAttributes, options); | ||
PublicationModel.__super__.set.call(this, changedAttributes, standardOpts); | ||
} | ||
@@ -176,14 +222,9 @@ | ||
// Trigger events for any nested objects. | ||
_.each(newAttributes, function (value, key, attributes) { | ||
_.each(changedAttributes, function (value, key, attributes) { | ||
if (_.isObject(value)) _this.trigger('change:' + key, _this, attributes[key], options); | ||
}); | ||
// If the new attributes were all nested objects, trigger a general `change` event too. | ||
var allObjects = _.every(newAttributes, function (v) { | ||
return _.isObject(v); | ||
}); | ||
// NOTE: Do not rely on this event passing the changed attributes. This does not conform to | ||
// Backbone's `change` event where the new attributes are not passed. | ||
if (allObjects) this.trigger('change', this, newAttributes, options); | ||
if (allChangesAreObjects) this.trigger('change', this, changedAttributes, options); | ||
} | ||
@@ -190,0 +231,0 @@ |
{ | ||
"name": "backbone-publication", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "Supports backbone classes backed by `publication-client` reactive queries.", | ||
@@ -5,0 +5,0 @@ "main": "dist/browser/index.js", |
@@ -38,2 +38,3 @@ # backbone-publication | ||
### Changelog | ||
* 1.0.5 - Changed `PublicationModel.set` to correctly fire `change` events for nested objects. | ||
* 1.0.4 - Reverted change on `PublicationModel.set` and added warning instead. | ||
@@ -40,0 +41,0 @@ * 1.0.3 - Fixed issue with `PublicationModel.set` not firing `change` event. |
@@ -84,2 +84,34 @@ import _ from 'underscore'; | ||
return _.isObject(obj) && !_.isArray(obj); | ||
}, | ||
/** | ||
* Performs a deep clone of an object. | ||
* @param {Object} source - the object to clone. | ||
* @returns {Object} a clone of the given object, where any descendent objects are themselves | ||
* cloned, and not just references to their respective counterpart in `source`. | ||
*/ | ||
deepClone: function(source) { | ||
var clone = _.clone(source); | ||
_.each(clone, (v,k) => { | ||
if (_.isObject(v)) { | ||
clone[k] = ObjectUtils.deepClone(v); | ||
} | ||
}); | ||
return clone; | ||
}, | ||
/** | ||
* Returns the changes between two objects. Includes attributes in `b` that are not in `a`, and | ||
* attributes that are in both `a` and `b` but where the values differ. Performs deep comparison | ||
* of objects and arrays. | ||
* @param {Object} a - the source object. | ||
* @param {Object} b - the comparison object. | ||
* @returns {Object} an object containing the attributes of `b` which differ from `a`. | ||
*/ | ||
changes: function(a, b) { | ||
const toReturn = {}; | ||
_.each(b, (v,k) => { | ||
if (!_.has(a, k) || !_.isEqual(a[k], v)) toReturn[k] = v; | ||
}); | ||
return toReturn; | ||
} | ||
@@ -86,0 +118,0 @@ }; |
@@ -72,10 +72,22 @@ import _ from 'underscore'; | ||
var oldAttributes = _.omit(this.attributes, '_id', 'createdAt'); | ||
var fullAttributes = ObjectUtils.deepExtend(oldAttributes, newAttributes); | ||
var fullAttributes = ObjectUtils.deepExtend(ObjectUtils.deepClone(oldAttributes), newAttributes); | ||
// Perform the standard Backbone.js set. Do this first, so when we trigger | ||
// events further down the new attributes are in place. | ||
/* Determine which attributes actually changed. This protects against things like the existing | ||
* value for an attribute being passed in. */ | ||
var changedAttributes = ObjectUtils.changes(oldAttributes, fullAttributes); | ||
// If there were no real changes, we can bail. | ||
var hasChanges = !_.isEmpty(changedAttributes); | ||
if (!hasChanges) return; | ||
/* Perform the standard Backbone.js set. Do this first, so when we trigger events further down | ||
* the new attributes are in place. We also determine if all the changes were to nested | ||
* objects - if so, we don't emit any events (but still call `set` so the new attributes are | ||
* stored on the model). */ | ||
var allChangesAreObjects = _.every(changedAttributes, v => _.isObject(v)); | ||
var standardOpts = _.extend({}, options, { silent: allChangesAreObjects }); | ||
if (options.unset) { | ||
PublicationModel.__super__.unset.call(this, fullAttributes, options); | ||
PublicationModel.__super__.unset.call(this, changedAttributes, standardOpts); | ||
} else { | ||
PublicationModel.__super__.set.call(this, fullAttributes, options); | ||
PublicationModel.__super__.set.call(this, changedAttributes, standardOpts); | ||
} | ||
@@ -85,14 +97,9 @@ | ||
// Trigger events for any nested objects. | ||
_.each(newAttributes, (value, key, attributes) => { | ||
_.each(changedAttributes, (value, key, attributes) => { | ||
if (_.isObject(value)) this.trigger('change:' + key, this, attributes[key], options); | ||
}); | ||
// If the new attributes were all nested objects, trigger a general `change` event too. | ||
var allObjects = _.every(newAttributes, function(v) { | ||
return _.isObject(v); | ||
}); | ||
// NOTE: Do not rely on this event passing the changed attributes. This does not conform to | ||
// Backbone's `change` event where the new attributes are not passed. | ||
if (allObjects) this.trigger('change', this, newAttributes, options); | ||
if (allChangesAreObjects) this.trigger('change', this, changedAttributes, options); | ||
} | ||
@@ -99,0 +106,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33347
744
44
1