Skip to content

Commit 85030d2

Browse files
committed
Merge pull request #140 from agoldis/master
issue #68 fix - changed `nestedChanges` and `_delayedTriggers` scope, added tests accordingly
2 parents 6f0e9cc + 68026be commit 85030d2

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

backbone-nested.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
}(this, function($, _, Backbone) {
2222
'use strict';
2323

24-
var _delayedTriggers = [],
25-
nestedChanges;
2624

2725
Backbone.NestedModel = Backbone.Model.extend({
2826

@@ -70,13 +68,13 @@
7068
}
7169
}
7270

73-
nestedChanges = Backbone.NestedModel.__super__.changedAttributes.call(this);
71+
this._nestedChanges = Backbone.NestedModel.__super__.changedAttributes.call(this);
7472

7573
if (opts.unset && attrPath && attrPath.length === 1){ // assume it is a singular attribute being unset
7674
// unsetting top-level attribute
7775
unsetObj = {};
7876
unsetObj[key] = void 0;
79-
nestedChanges = _.omit(nestedChanges, _.keys(unsetObj));
77+
this._nestedChanges = _.omit(this._nestedChanges, _.keys(unsetObj));
8078
validated = Backbone.NestedModel.__super__.set.call(this, unsetObj, opts);
8179
} else {
8280
unsetObj = newAttrs;
@@ -89,15 +87,15 @@
8987
} else if (opts.unset && _.isObject(key)) {
9088
unsetObj = key;
9189
}
92-
nestedChanges = _.omit(nestedChanges, _.keys(unsetObj));
90+
this._nestedChanges = _.omit(this._nestedChanges, _.keys(unsetObj));
9391
validated = Backbone.NestedModel.__super__.set.call(this, unsetObj, opts);
9492
}
9593

9694

9795
if (!validated){
9896
// reset changed attributes
9997
this.changed = {};
100-
nestedChanges = {};
98+
this._nestedChanges = {};
10199
return false;
102100
}
103101

@@ -111,7 +109,7 @@
111109
},
112110

113111
clear: function(options) {
114-
nestedChanges = {};
112+
this._nestedChanges = {};
115113

116114
// Mostly taken from Backbone.Model.set, modified to work for NestedModel.
117115
options = options || {};
@@ -199,7 +197,7 @@
199197
changedAttributes: function(diff) {
200198
var backboneChanged = Backbone.NestedModel.__super__.changedAttributes.call(this, diff);
201199
if (_.isObject(backboneChanged)) {
202-
return _.extend({}, nestedChanges, backboneChanged);
200+
return _.extend({}, this._nestedChanges, backboneChanged);
203201
}
204202
return false;
205203
},
@@ -210,8 +208,14 @@
210208

211209

212210
// private
211+
_getDelayedTriggers: function(){
212+
if (typeof this._delayedTriggers === "undefined"){
213+
this._delayedTriggers = [];
214+
}
215+
return this._delayedTriggers;
216+
},
213217
_delayedTrigger: function(/* the trigger args */){
214-
_delayedTriggers.push(arguments);
218+
this._getDelayedTriggers().push(arguments);
215219
},
216220

217221
_delayedChange: function(attrStr, newVal, options){
@@ -227,8 +231,8 @@
227231
},
228232

229233
_runDelayedTriggers: function(){
230-
while (_delayedTriggers.length > 0){
231-
this.trigger.apply(this, _delayedTriggers.shift());
234+
while (this._getDelayedTriggers().length > 0){
235+
this.trigger.apply(this, this._getDelayedTriggers().shift());
232236
}
233237
},
234238

test/nested-model.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,5 +1116,35 @@ $(document).ready(function() {
11161116

11171117
equal(model, doc);
11181118
});
1119+
test("issue #68 - _delayedTriggers is a singleton", function() {
1120+
var modelA = new Klass({
1121+
modelName: "modelA",
1122+
name: {
1123+
first: "andrew",
1124+
last: "goldis"
1125+
}
1126+
});
1127+
var modelB = new Klass({
1128+
modelName: "modelB",
1129+
name: {
1130+
first: "eyal",
1131+
last: "keren"
1132+
}
1133+
});
1134+
// trigger a set on modelB when modelA is changed to create the issue of singleton _delayedTriggers
1135+
// the buggy behavior cause modelB to trigger modelA _delayedTriggers
1136+
modelA.on("change:name", function(){
1137+
modelB.set("and.now.for.something.completely", "different");
1138+
});
1139+
// assert true (expected behavior)
1140+
modelA.on("change:name.first", function(){
1141+
ok(true, "event change:name.first from modelA was triggered on modelA - great!");
1142+
});
1143+
// assert false (buggy behavior)
1144+
modelB.on("change:name.first", function(){
1145+
ok(false, "event change:name.first from modelA was triggered on modelB - ouch!");
1146+
});
11191147

1148+
modelA.set("name.first", "s");
1149+
});
11201150
});

0 commit comments

Comments
 (0)