Просмотр исходного кода

change how the RunQueue is used

Adam Shaw 9 лет назад
Родитель
Сommit
4e2abec849
2 измененных файлов с 65 добавлено и 47 удалено
  1. 1 20
      src/common/RunQueue.js
  2. 64 27
      src/common/View.js

+ 1 - 20
src/common/RunQueue.js

@@ -4,7 +4,6 @@
 function RunQueue() {
 	var _this = this;
 	var q = []; // array of runFuncs
-	var completedCnt = 0;
 
 	$.extend(this, EmitterMixin);
 
@@ -19,8 +18,7 @@ function RunQueue() {
 					.then(function() {
 						q.shift(); // pop itself off
 
-						completedCnt++;
-						_this.trigger('add');
+						_this.trigger('ran');
 
 						// run the next task, if any
 						if (q.length) {
@@ -38,23 +36,6 @@ function RunQueue() {
 			}
 		});
 	};
-
-	this.completed = function() {
-		return completedCnt;
-	};
-
-	this.forgetCompleted = function() {
-		completedCnt = 0;
-	};
-
-	this.promise = function() {
-		if (this.completedCnt) {
-			return Promise.resolve();
-		}
-		return new Promise(function(resolve) {
-			_this.one('add', resolve);
-		});
-	};
 }
 
 FC.RunQueue = RunQueue;

+ 64 - 27
src/common/View.js

@@ -13,10 +13,12 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	el: null, // the view's containing element. set by Calendar
 
 	isDateSet: false,
+	isDateRendered: false,
 	dateRenderQueue: null,
 
 	isEventsBound: false,
 	isEventsSet: false,
+	isEventsRendered: false,
 	eventRenderQueue: null,
 
 	// range the view is actually displaying (moments)
@@ -357,6 +359,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	},
 
 
+	// if date not specified, uses current
 	resetDate: function(date, forcedScroll) {
 		var _this = this;
 
@@ -379,11 +382,15 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	},
 
 
+	// if date not specified, uses current
 	requestRenderDate: function(date, forcedScroll) {
 		var _this = this;
 
 		return this.dateRenderQueue.add(function() {
-			_this.setRange(_this.computeRange(date));
+
+			if (date) {
+				_this.setRange(_this.computeRange(date));
+			}
 
 			_this.captureInitialScroll(forcedScroll);
 			_this.freezeHeight();
@@ -400,6 +407,8 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 			_this.thawHeight();
 			_this.releaseScroll();
 
+			_this.isDateRendered = true;
+
 			_this.triggerDateRender();
 		});
 	},
@@ -410,9 +419,8 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 		return this.dateRenderQueue.add(function() {
 			return _this.requestUnrenderEvents().then(function() {
-				// there will be so much destruction, we don't care about freezing height or maintaining scroll
 
-				_this.dateRenderQueue.forgetCompleted();
+				// there will be so much destruction, we don't care about freezing height or maintaining scroll
 
 				_this.unselect();
 				_this.stopNowIndicator();
@@ -423,11 +431,34 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 				if (_this.destroy) {
 					_this.destroy(); // TODO: deprecate
 				}
+
+				_this.isDateRendered = false;
 			});
 		});
 	},
 
 
+	requestRerenderDate: function() {
+		var _this = this;
+		var wasEventsSet = this.isEventsSet;
+
+		this.captureScroll();
+		this.freezeHeight();
+
+		this.requestUnrenderDate();
+		return this.requestRenderDate().then(function() { // will use current date
+
+			// events were cleared, so rerender them
+			if (wasEventsSet) {
+				_this.resetEvents();
+			}
+
+			_this.thawHeight();
+			_this.releaseScroll();
+		});
+	},
+
+
 	// date-cell content only
 	renderDates: function() {
 		// subclasses should implement
@@ -644,10 +675,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 	captureScroll: function() {
 		if (!(this.capturedScrollDepth++)) {
-			this.capturedScroll =
-				this.dateRenderQueue.completed() ? // guarantee a render before querying scroll
-					this.queryScroll() :
-					{};
+			this.capturedScroll = this.isDateRendered ? this.queryScroll() : {}; // require a render first
 			return true; // root?
 		}
 		return false;
@@ -789,17 +817,21 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	},
 
 
+	// if `events` not specified, uses current
 	resetEvents: function(events) {
 		var _this = this;
 
-		// do this before unsetEvents, a destructive action
-		this.captureScroll();
-		this.freezeHeight();
+		return Promise.resolve(events || this.requestEvents()).then(function(events) {
 
-		this.unsetEvents();
-		return this.setEvents(events).then(function() {
-			_this.thawHeight();
-			_this.releaseScroll();
+			// do this before unsetEvents, a destructive action
+			_this.captureScroll();
+			_this.freezeHeight();
+
+			_this.unsetEvents();
+			return _this.setEvents(events).then(function() { // TODO: non-lazy fetching might go crazy
+				_this.thawHeight();
+				_this.releaseScroll();
+			});
 		});
 	},
 
@@ -819,25 +851,33 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 		var _this = this;
 
 		return this.eventRenderQueue.add(function() {
-			_this.captureScroll();
-			_this.freezeHeight();
+			return _this.resolveEventRenderDeps().then(function() {
+				_this.captureScroll();
+				_this.freezeHeight();
 
-			_this.renderEvents(events);
+				_this.renderEvents(events);
 
-			_this.thawHeight();
-			_this.releaseScroll();
+				_this.thawHeight();
+				_this.releaseScroll();
 
-			_this.triggerEventRender();
+				_this.isEventsRendered = true;
+
+				_this.triggerEventRender();
+			});
 		});
 	},
 
 
+	// executes prerequs for event rendering. returns a promise that resolves when ready.
+	resolveEventRenderDeps: function() {
+		return Promise.resolve(); // nothing at the moment
+	},
+
+
 	requestUnrenderEvents: function() { // assumes there was already at least one job in eventRenderQueue
 		var _this = this;
 
 		return this.eventRenderQueue.add(function() {
-			_this.eventRenderQueue.forgetCompleted(); // for ensureRenderEvents
-
 			_this.triggerEventUnrender();
 
 			_this.captureScroll();
@@ -851,12 +891,9 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 			_this.thawHeight();
 			_this.releaseScroll();
-		});
-	},
 
-
-	ensureRenderEvents: function() {
-		return this.eventRenderQueue.promise();
+			_this.isEventsRendered = false;
+		});
 	},