Przeglądaj źródła

View.watch refactor

Adam Shaw 8 lat temu
rodzic
commit
ad3eb5d72e
4 zmienionych plików z 100 dodań i 285 usunięć
  1. 1 5
      src/Calendar.js
  2. 0 5
      src/EventManager.js
  3. 5 5
      src/common/View.date-range.js
  4. 94 270
      src/common/View.js

+ 1 - 5
src/Calendar.js

@@ -772,11 +772,7 @@ function Calendar_constructor(element, overrides) {
 					currentView.captureInitialScroll(forcedScroll);
 				}
 
-				currentView.setDate(t.currentDate);
-
-				// TODO: make setDate return the revised date.
-				// Difficult because of the pseudo-async nature, promises.
-				t.currentDate = currentView.currentDate;
+				t.currentDate = currentView.setDate(t.currentDate);
 
 				if (forcedScroll) {
 					currentView.releaseScroll();

+ 0 - 5
src/EventManager.js

@@ -99,11 +99,6 @@ function EventManager() { // assumed to be a calendar
 	};
 
 
-	t.getPrunedEventCache = function() {
-		return prunedCache;
-	};
-
-
 
 	/* Fetching
 	-----------------------------------------------------------------------------*/

+ 5 - 5
src/common/View.date-range.js

@@ -20,10 +20,6 @@ View.mixin({
 	// how far the current date will move for a prev/next operation
 	dateIncrement: null,
 
-	// stores the *calendar's* current date after setDate
-	// TODO: entirely Calendar's responsibility
-	currentDate: null,
-
 	minTime: null, // Duration object that denotes the first visible time of any given day
 	maxTime: null, // Duration object that denotes the exclusive visible end time of any given day
 	usesMinMaxTime: false, // whether minTime/maxTime will affect the activeRange. Views must opt-in.
@@ -51,7 +47,6 @@ View.mixin({
 		this.activeRange = dateProfile.activeRange;
 		this.validRange = dateProfile.validRange;
 		this.dateIncrement = dateProfile.dateIncrement;
-		this.currentDate = dateProfile.date;
 		this.minTime = dateProfile.minTime;
 		this.maxTime = dateProfile.maxTime;
 
@@ -63,6 +58,11 @@ View.mixin({
 	},
 
 
+	unsetDateProfile: function() {
+		this.activeRange = null;
+	},
+
+
 	// Builds a structure with info about what the dates/ranges will be for the "prev" view.
 	buildPrevDateProfile: function(date) {
 		var prevDate = date.clone().startOf(this.currentRangeUnit).subtract(this.dateIncrement);

+ 94 - 270
src/common/View.js

@@ -2,7 +2,7 @@
 /* An abstract class from which other views inherit from
 ----------------------------------------------------------------------------------------------------------------------*/
 
-var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
+var View = FC.View = Model.extend({
 
 	type: null, // subclass' view name (string)
 	name: null, // deprecated. use `type` instead
@@ -13,14 +13,9 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	options: null, // hash containing all options. already merged with view-specific-options
 	el: null, // the view's containing element. set by Calendar
 
-	isDateSet: false,
-	isDateRendered: false,
-	dateRenderQueue: null,
-
-	isEventsBound: false,
-	isEventsSet: false,
+	renderQueue: null,
+	isDatesRendered: false,
 	isEventsRendered: false,
-	eventRenderQueue: null,
 
 	isRTL: false,
 	isSelected: false, // boolean whether a range of time is user-selected or not
@@ -46,6 +41,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 
 	constructor: function(calendar, viewSpec) {
+		Model.prototype.constructor.call(this);
 
 		this.calendar = calendar;
 		this.viewSpec = viewSpec;
@@ -64,8 +60,8 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 		this.eventOrderSpecs = parseFieldSpecs(this.opt('eventOrder'));
 
-		this.dateRenderQueue = new TaskQueue();
-		this.eventRenderQueue = new TaskQueue(this.opt('eventRenderWait'));
+		// TODO: differentiate eventRenderWait from date rendering
+		this.renderQueue = new TaskQueue(this.opt('eventRenderWait'));
 
 		this.initialize();
 	},
@@ -97,29 +93,6 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	},
 
 
-	// Returns a proxy of the given promise that will be rejected if the given event fires
-	// before the promise resolves.
-	rejectOn: function(eventName, promise) {
-		var _this = this;
-
-		return new Promise(function(resolve, reject) {
-			_this.one(eventName, reject);
-
-			function cleanup() {
-				_this.off(eventName, reject);
-			}
-
-			promise.then(function(res) { // success
-				cleanup();
-				resolve(res);
-			}, function() { // failure
-				cleanup();
-				reject();
-			});
-		});
-	},
-
-
 	/* Title and Date Formatting
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -288,60 +261,20 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 
 	setDate: function(date) {
-		var isReset = this.isDateSet;
-
-		this.isDateSet = true;
-		this.handleRawDate(date);
-		this.trigger(isReset ? 'dateReset' : 'dateSet', date);
-	},
-
-
-	unsetDate: function() {
-		if (this.isDateSet) {
-			this.isDateSet = false;
-			this.handleDateUnset();
-			this.trigger('dateUnset');
-		}
-	},
-
-
-	// Date Handling
-	// -----------------------------------------------------------------------------------------------------------------
-
-
-	handleRawDate: function(date) {
-		var _this = this;
 		var dateProfile = this.buildDateProfile(date, null, true); // forceToValid=true
 
-		if (!this.isSameDateProfile(dateProfile)) { // real change
-			this.handleDate(dateProfile);
+		if (!this.isSameDateProfile(dateProfile)) {
+			this.setDateProfile(dateProfile);
+			this.set('dateProfile', dateProfile); // for watchers
 		}
-		else {
-			// View might have no date change, but still needs to render (because of a view unrender/rerender).
-			// Wait for possible queued unrenders. TODO: refactor.
-			this.dateRenderQueue.add(function() {
-				if (!_this.isDateRendered) {
-					_this.handleDate(dateProfile);
-				}
-			});
-		}
-	},
 
-
-	handleDate: function(dateProfile) {
-		var _this = this;
-
-		this.unbindEvents(); // will do nothing if not already bound
-		this.requestDateRender(dateProfile).then(function() {
-			// wish we could start earlier, but setDateProfile needs to execute first
-			_this.bindEvents(); // will request events
-		});
+		return dateProfile.date;
 	},
 
 
-	handleDateUnset: function() {
-		this.unbindEvents();
-		this.requestDateUnrender();
+	unsetDate: function() {
+		this.unsetDateProfile();
+		this.unset('dateProfile'); // for watchers
 	},
 
 
@@ -353,7 +286,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	requestDateRender: function(dateProfile) {
 		var _this = this;
 
-		return this.dateRenderQueue.add(function() {
+		return this.renderQueue.add(function() {
 			return _this.executeDateRender(dateProfile);
 		});
 	},
@@ -362,7 +295,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	requestDateUnrender: function() {
 		var _this = this;
 
-		return this.dateRenderQueue.add(function() {
+		return this.renderQueue.add(function() {
 			return _this.executeDateUnrender();
 		});
 	},
@@ -374,10 +307,9 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 	// if dateProfile not specified, uses current
 	executeDateRender: function(dateProfile) {
-		var _this = this;
 
 		if (dateProfile) {
-			_this.setDateProfile(dateProfile);
+			this.setDateProfile(dateProfile);
 		}
 
 		this.updateTitle();
@@ -393,60 +325,34 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 		this.freezeHeight();
 
-		// potential issue: date-unrendering will happen with the *new* range
-		return this.executeDateUnrender().then(function() {
-
-			if (_this.render) {
-				_this.render(); // TODO: deprecate
-			}
-
-			_this.renderDates();
-			_this.updateSize();
-			_this.renderBusinessHours(); // might need coordinates, so should go after updateSize()
-			_this.startNowIndicator();
+		if (this.render) {
+			this.render(); // TODO: deprecate
+		}
 
-			_this.thawHeight();
-			_this.releaseScroll();
+		this.renderDates();
+		this.updateSize();
+		this.renderBusinessHours(); // might need coordinates, so should go after updateSize()
+		this.startNowIndicator();
 
-			_this.isDateRendered = true;
-			_this.onDateRender();
-			_this.trigger('dateRender');
-		});
+		this.thawHeight();
+		this.releaseScroll();
+		this.isDatesRendered = true;
+		this.triggerRender(); // TODO: revisit this
 	},
 
 
 	executeDateUnrender: function() {
-		var _this = this;
-
-		if (_this.isDateRendered) {
-			return this.requestEventsUnrender().then(function() {
-
-				_this.unselect();
-				_this.stopNowIndicator();
-				_this.triggerUnrender();
-				_this.unrenderBusinessHours();
-				_this.unrenderDates();
-
-				if (_this.destroy) {
-					_this.destroy(); // TODO: deprecate
-				}
-
-				_this.isDateRendered = false;
-				_this.trigger('dateUnrender');
-			});
+		this.unselect();
+		this.stopNowIndicator();
+		this.triggerUnrender();
+		this.unrenderBusinessHours();
+		this.unrenderDates();
+
+		if (this.destroy) {
+			this.destroy(); // TODO: deprecate
 		}
-		else {
-			return Promise.resolve();
-		}
-	},
-
 
-	// Date Rendering Triggers
-	// -----------------------------------------------------------------------------------------------------------------
-
-
-	onDateRender: function() {
-		this.triggerRender();
+		this.isDatesRendered = false;
 	},
 
 
@@ -666,7 +572,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 	captureScroll: function() {
 		if (!(this.capturedScrollDepth++)) {
-			this.capturedScroll = this.isDateRendered ? this.queryScroll() : {}; // require a render first
+			this.capturedScroll = this.isDatesRendered ? this.queryScroll() : {}; // require a render first
 			return true; // root?
 		}
 		return false;
@@ -761,83 +667,6 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	},
 
 
-	// Event Binding/Unbinding
-	// -----------------------------------------------------------------------------------------------------------------
-
-
-	bindEvents: function() {
-		var _this = this;
-
-		if (!this.isEventsBound) {
-			this.isEventsBound = true;
-			this.rejectOn('eventsUnbind', this.requestEvents()).then(function(events) { // TODO: test rejection
-				_this.listenTo(_this.calendar, 'eventsReset', _this.setEvents);
-				_this.setEvents(events);
-			});
-		}
-	},
-
-
-	unbindEvents: function() {
-		if (this.isEventsBound) {
-			this.isEventsBound = false;
-			this.stopListeningTo(this.calendar, 'eventsReset');
-			this.unsetEvents();
-			this.trigger('eventsUnbind');
-		}
-	},
-
-
-	// Event Setting/Unsetting
-	// -----------------------------------------------------------------------------------------------------------------
-
-
-	setEvents: function(events) {
-		var isReset = this.isEventSet;
-
-		this.isEventsSet = true;
-		this.handleEvents(events, isReset);
-		this.trigger(isReset ? 'eventsReset' : 'eventsSet', events);
-	},
-
-
-	unsetEvents: function() {
-		if (this.isEventsSet) {
-			this.isEventsSet = false;
-			this.handleEventsUnset();
-			this.trigger('eventsUnset');
-		}
-	},
-
-
-	whenEventsSet: function() {
-		var _this = this;
-
-		if (this.isEventsSet) {
-			return Promise.resolve(this.getCurrentEvents());
-		}
-		else {
-			return new Promise(function(resolve) {
-				_this.one('eventsSet', resolve);
-			});
-		}
-	},
-
-
-	// Event Handling
-	// -----------------------------------------------------------------------------------------------------------------
-
-
-	handleEvents: function(events, isReset) {
-		this.requestEventsRender(events);
-	},
-
-
-	handleEventsUnset: function() {
-		this.requestEventsUnrender();
-	},
-
-
 	// Event Render Queuing
 	// -----------------------------------------------------------------------------------------------------------------
 
@@ -846,8 +675,8 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	requestEventsRender: function(events) {
 		var _this = this;
 
-		return this.eventRenderQueue.add(function() { // might not return a promise if debounced!? bad
-			return _this.executeEventsRender(events);
+		this.renderQueue.add(function() {
+			_this.executeEventsRender(events);
 		});
 	},
 
@@ -855,24 +684,9 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	requestEventsUnrender: function() {
 		var _this = this;
 
-		if (this.isEventsRendered) {
-			return this.eventRenderQueue.addQuickly(function() {
-				return _this.executeEventsUnrender();
-			});
-		}
-		else {
-			return Promise.resolve();
-		}
-	},
-
-
-	requestCurrentEventsRender: function() {
-		if (this.isEventsSet) {
-			this.requestEventsRender(this.getCurrentEvents());
-		}
-		else {
-			return Promise.reject();
-		}
+		this.renderQueue.addQuickly(function() {
+			_this.executeEventsUnrender();
+		});
 	},
 
 
@@ -881,45 +695,35 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 
 
 	executeEventsRender: function(events) {
-		var _this = this;
-
 		this.captureScroll();
 		this.freezeHeight();
 
-		return this.executeEventsUnrender().then(function() {
-			_this.renderEvents(events);
+		this.renderEvents(events);
 
-			_this.thawHeight();
-			_this.releaseScroll();
+		this.thawHeight();
+		this.releaseScroll();
 
-			_this.isEventsRendered = true;
-			_this.onEventsRender();
-			_this.trigger('eventsRender');
-		});
+		this.isEventsRendered = true;
+		this.onEventsRender();
 	},
 
 
 	executeEventsUnrender: function() {
-		if (this.isEventsRendered) {
-			this.onBeforeEventsUnrender();
+		this.onBeforeEventsUnrender();
 
-			this.captureScroll();
-			this.freezeHeight();
+		this.captureScroll();
+		this.freezeHeight();
 
-			if (this.destroyEvents) {
-				this.destroyEvents(); // TODO: deprecate
-			}
+		if (this.destroyEvents) {
+			this.destroyEvents(); // TODO: deprecate
+		}
 
-			this.unrenderEvents();
+		this.unrenderEvents();
 
-			this.thawHeight();
-			this.releaseScroll();
+		this.thawHeight();
+		this.releaseScroll();
 
-			this.isEventsRendered = false;
-			this.trigger('eventsUnrender');
-		}
-
-		return Promise.resolve(); // always synchronous
+		this.isEventsRendered = false;
 	},
 
 
@@ -960,23 +764,6 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	},
 
 
-	// Event Data Access
-	// -----------------------------------------------------------------------------------------------------------------
-
-
-	requestEvents: function() {
-		return this.calendar.requestEvents(
-			this.activeRange.start,
-			this.activeRange.end
-		);
-	},
-
-
-	getCurrentEvents: function() {
-		return this.calendar.getPrunedEventCache();
-	},
-
-
 	// Event Rendering Utils
 	// -----------------------------------------------------------------------------------------------------------------
 
@@ -1380,3 +1167,40 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
 	}
 
 });
+
+
+View.watch('displayingDates', [ 'dateProfile' ], function(deps) {
+	this.requestDateRender(deps.dateProfile);
+}, function() {
+	this.requestDateUnrender();
+});
+
+
+View.watch('initialEvents', [ 'dateProfile' ], function(deps) {
+	return this.calendar.requestEvents(
+		deps.dateProfile.activeRange.start,
+		deps.dateProfile.activeRange.end
+	);
+});
+
+
+View.watch('bindingEvents', [ 'initialEvents' ], function(deps) {
+	var _this = this;
+
+	this.listenTo(this.calendar, 'eventsReset', function(events) {
+		_this.set('currentEvents', events);
+	});
+
+	// initially set
+	this.set('currentEvents', deps.initialEvents);
+}, function() {
+	this.stopListeningTo(this.calendar, 'eventsReset');
+	this.unset('currentEvents');
+});
+
+
+View.watch('displayingEvents', [ 'displayingDates', 'currentEvents' ], function(deps) {
+	this.requestEventsRender(deps.currentEvents);
+}, function() {
+	this.requestEventsUnrender();
+});