Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #86 from walmartlabs/loading-fixes

Fix loading
  • Loading branch information...
commit 63132e5dff823678a0d5634a101791ecf647b52b 2 parents 932ed3f + d6d6983
@Candid Candid authored
Showing with 70 additions and 29 deletions.
  1. +24 −24 src/loading.js
  2. +46 −5 test/src/loading.js
View
48 src/loading.js
@@ -8,15 +8,18 @@ Thorax.setRootObject = function(obj) {
};
Thorax.loadHandler = function(start, end, context) {
+ var loadCounter = _.uniqueId();
return function(message, background, object) {
var self = context || this;
+ self._loadInfo = self._loadInfo || [];
+ var loadInfo = self._loadInfo[loadCounter];
function startLoadTimeout() {
- clearTimeout(self._loadStart.timeout);
- self._loadStart.timeout = setTimeout(function() {
+ clearTimeout(loadInfo.timeout);
+ loadInfo.timeout = setTimeout(function() {
try {
- self._loadStart.run = true;
- start.call(self, self._loadStart.message, self._loadStart.background, self._loadStart);
+ loadInfo.run = true;
+ start.call(self, loadInfo.message, loadInfo.background, loadInfo);
} catch (e) {
Thorax.onException('loadStart', e);
}
@@ -24,14 +27,11 @@ Thorax.loadHandler = function(start, end, context) {
loadingTimeout * 1000);
}
- if (!self._loadStart) {
- var loadingTimeout = self._loadingTimeoutDuration;
- if (loadingTimeout === void 0) {
- // If we are running on a non-view object pull the default timeout
- loadingTimeout = Thorax.View.prototype._loadingTimeoutDuration;
- }
+ if (!loadInfo) {
+ var loadingTimeout = self._loadingTimeoutDuration !== undefined ?
+ self._loadingTimeoutDuration : Thorax.View.prototype._loadingTimeoutDuration;
- self._loadStart = _.extend({
+ loadInfo = self._loadInfo[loadCounter] = _.extend({
events: [],
timeout: 0,
message: message,
@@ -39,16 +39,16 @@ Thorax.loadHandler = function(start, end, context) {
}, Backbone.Events);
startLoadTimeout();
} else {
- clearTimeout(self._loadStart.endTimeout);
+ clearTimeout(loadInfo.endTimeout);
- self._loadStart.message = message;
- if (!background && self._loadStart.background) {
- self._loadStart.background = false;
+ loadInfo.message = message;
+ if (!background && loadInfo.background) {
+ loadInfo.background = false;
startLoadTimeout();
}
}
- self._loadStart.events.push(object);
+ loadInfo.events.push(object);
object.on(loadEnd, function endCallback() {
object.off(loadEnd, endCallback);
@@ -58,26 +58,26 @@ Thorax.loadHandler = function(start, end, context) {
loadingEndTimeout = Thorax.View.prototype._loadingTimeoutEndDuration;
}
- var events = self._loadStart.events,
+ var events = loadInfo.events,
index = events.indexOf(object);
if (index >= 0) {
events.splice(index, 1);
}
if (!events.length) {
- self._loadStart.endTimeout = setTimeout(function() {
+ loadInfo.endTimeout = setTimeout(function() {
try {
if (!events.length) {
- var run = self._loadStart.run;
+ var run = loadInfo.run;
if (run) {
// Emit the end behavior, but only if there is a paired start
- end.call(self, self._loadStart.background, self._loadStart);
- self._loadStart.trigger(loadEnd, self._loadStart);
+ end.call(self, loadInfo.background, loadInfo);
+ loadInfo.trigger(loadEnd, loadInfo);
}
// If stopping make sure we don't run a start
- clearTimeout(self._loadStart.timeout);
- self._loadStart = undefined;
+ clearTimeout(loadInfo.timeout);
+ loadInfo = self._loadInfo[loadCounter] = undefined;
}
} catch (e) {
Thorax.onException('loadEnd', e);
@@ -125,7 +125,7 @@ Thorax.mixinLoadable = function(target, useParent) {
// Propagates loading view parameters to the AJAX layer
onLoadStart: function(message, background, object) {
var that = useParent ? this.parent : this;
- if (!that.nonBlockingLoad && !background && rootObject) {
+ if (!that.nonBlockingLoad && !background && rootObject && rootObject !== this) {
rootObject.trigger(loadStart, message, background, object);
}
$(that.el).addClass(that._loadingClassName);
View
51 test/src/loading.js
@@ -245,7 +245,7 @@ describe('loading', function() {
it('pair with timeout registers', function() {
this.object.loadStart('foo', false);
this.clock.tick(1000);
- var loaderWrapper = this.object._loadStart;
+ var loaderWrapper = this.object._loadInfo[this.object._loadInfo.length - 1];
this.object.loadEnd();
this.clock.tick(1000);
@@ -257,7 +257,7 @@ describe('loading', function() {
it('consequtive pairs emit one event', function() {
this.object.loadStart('foo', false);
this.clock.tick(1000);
- var loaderWrapper = this.object._loadStart;
+ var loaderWrapper = this.object._loadInfo[this.object._loadInfo.length - 1];
this.object.loadEnd();
this.clock.tick(10);
@@ -277,7 +277,7 @@ describe('loading', function() {
it('consequtive pairs emit two events after timeout', function() {
this.object.loadStart('foo', false);
this.clock.tick(1000);
- var loaderWrapper = this.object._loadStart;
+ var loaderWrapper = this.object._loadInfo[this.object._loadInfo.length - 1];
this.object.loadEnd();
this.clock.tick(1000);
@@ -287,7 +287,7 @@ describe('loading', function() {
this.object.loadStart('bar', true);
this.clock.tick(1000);
- var loaderWrapper2 = this.object._loadStart;
+ var loaderWrapper2 = this.object._loadInfo[this.object._loadInfo.length - 1];
this.object.loadEnd();
this.clock.tick(1000);
@@ -299,7 +299,7 @@ describe('loading', function() {
it('overlapping pairs emit one event', function() {
this.object.loadStart('foo', false);
this.clock.tick(1000);
- var loaderWrapper = this.object._loadStart;
+ var loaderWrapper = this.object._loadInfo[this.object._loadInfo.length - 1];
this.object.loadStart('bar', true);
this.clock.tick(1000);
@@ -315,6 +315,47 @@ describe('loading', function() {
expect(this.loads).to.eql([{msg: 'foo', background: false, model: loaderWrapper}]);
expect(this.ends).to.eql([{background: false, model: loaderWrapper}]);
});
+
+ it('loadHandlers are isolated', function() {
+ var startSpy = this.spy(),
+ endSpy = this.spy();
+ this.object.on('load:start', Thorax.loadHandler(startSpy, endSpy));
+ this.object.loadStart('foo', false);
+
+ expect(this.loads.length).to.equal(0);
+ expect(this.ends.length).to.equal(0);
+ expect(startSpy).to.not.have.been.called;
+ expect(endSpy).to.not.have.been.called;
+
+ this.clock.tick(200);
+
+ expect(this.loads.length).to.equal(0);
+ expect(this.ends.length).to.equal(0);
+ expect(startSpy).to.not.have.been.called;
+ expect(endSpy).to.not.have.been.called;
+
+ this.clock.tick(1000);
+
+ expect(this.loads.length).to.equal(1);
+ expect(this.ends.length).to.equal(0);
+ expect(startSpy).to.have.been.calledOnce;
+ expect(endSpy).to.not.have.been.called;
+
+ this.object.loadEnd();
+
+ expect(this.loads.length).to.equal(1);
+ expect(this.ends.length).to.equal(0);
+ expect(startSpy).to.have.been.calledOnce;
+ expect(endSpy).to.not.have.been.called;
+
+ this.clock.tick(1000);
+
+ expect(this.loads.length).to.equal(1);
+ expect(this.ends.length).to.equal(1);
+ expect(startSpy).to.have.been.calledOnce;
+ expect(endSpy).to.have.been.calledOnce;
+
+ });
});
Please sign in to comment.
Something went wrong with that request. Please try again.