瀏覽代碼

ChronoComponent children

Adam Shaw 8 年之前
父節點
當前提交
b51c5f28ea
共有 5 個文件被更改,包括 117 次插入246 次删除
  1. 4 114
      src/agenda/AgendaView.js
  2. 4 97
      src/basic/BasicView.js
  3. 107 20
      src/common/ChronoComponent.js
  4. 0 7
      src/common/View.js
  5. 2 8
      src/list/ListView.js

+ 4 - 114
src/agenda/AgendaView.js

@@ -28,9 +28,11 @@ var AgendaView = FC.AgendaView = View.extend({
 
 	initialize: function() {
 		this.timeGrid = this.instantiateTimeGrid();
+		this.addChild(this.timeGrid);
 
 		if (this.opt('allDaySlot')) { // should we display the "all-day" area?
 			this.dayGrid = this.instantiateDayGrid(); // the all-day subcomponent of this view
+			this.addChild(this.dayGrid);
 		}
 
 		this.scroller = new Scroller({
@@ -106,6 +108,7 @@ var AgendaView = FC.AgendaView = View.extend({
 
 	// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
 	// always completely kill each grid's rendering.
+	// TODO: move this over to ChronoComponent
 	unrenderDates: function() {
 		this.timeGrid.unrenderDates();
 		this.timeGrid.removeElement();
@@ -153,28 +156,6 @@ var AgendaView = FC.AgendaView = View.extend({
 	},
 
 
-	/* Business Hours
-	------------------------------------------------------------------------------------------------------------------*/
-
-
-	renderBusinessHours: function() {
-		this.timeGrid.renderBusinessHours();
-
-		if (this.dayGrid) {
-			this.dayGrid.renderBusinessHours();
-		}
-	},
-
-
-	unrenderBusinessHours: function() {
-		this.timeGrid.unrenderBusinessHours();
-
-		if (this.dayGrid) {
-			this.dayGrid.unrenderBusinessHours();
-		}
-	},
-
-
 	/* Now Indicator
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -184,16 +165,6 @@ var AgendaView = FC.AgendaView = View.extend({
 	},
 
 
-	renderNowIndicator: function(date) {
-		this.timeGrid.renderNowIndicator(date);
-	},
-
-
-	unrenderNowIndicator: function() {
-		this.timeGrid.unrenderNowIndicator();
-	},
-
-
 	/* Dimensions
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -309,49 +280,6 @@ var AgendaView = FC.AgendaView = View.extend({
 	// forward all hit-related method calls to the grids (dayGrid might not be defined)
 
 
-	hitsNeeded: function() {
-		this.timeGrid.hitsNeeded();
-		if (this.dayGrid) {
-			this.dayGrid.hitsNeeded();
-		}
-	},
-
-
-	hitsNotNeeded: function() {
-		this.timeGrid.hitsNotNeeded();
-		if (this.dayGrid) {
-			this.dayGrid.hitsNotNeeded();
-		}
-	},
-
-
-	prepareHits: function() {
-		this.timeGrid.prepareHits();
-		if (this.dayGrid) {
-			this.dayGrid.prepareHits();
-		}
-	},
-
-
-	releaseHits: function() {
-		this.timeGrid.releaseHits();
-		if (this.dayGrid) {
-			this.dayGrid.releaseHits();
-		}
-	},
-
-
-	queryHit: function(left, top) {
-		var hit = this.timeGrid.queryHit(left, top);
-
-		if (!hit && this.dayGrid) {
-			hit = this.dayGrid.queryHit(left, top);
-		}
-
-		return hit;
-	},
-
-
 	getHitSpan: function(hit) {
 		// TODO: hit.component is set as a hack to identify where the hit came from
 		return hit.component.getHitSpan(hit);
@@ -393,32 +321,11 @@ var AgendaView = FC.AgendaView = View.extend({
 		}
 
 		// the all-day area is flexible and might have a lot of events, so shift the height
+		// TODO: how will ChronoComponent handle this?
 		this.updateHeight();
 	},
 
 
-	// Retrieves all segment objects that are rendered in the view
-	getEventSegs: function() {
-		return this.timeGrid.getEventSegs().concat(
-			this.dayGrid ? this.dayGrid.getEventSegs() : []
-		);
-	},
-
-
-	// Unrenders all event elements and clears internal segment data
-	unrenderEvents: function() {
-
-		// unrender the events in the subcomponents
-		this.timeGrid.unrenderEvents();
-		if (this.dayGrid) {
-			this.dayGrid.unrenderEvents();
-		}
-
-		// we DON'T need to call updateHeight() because
-		// a renderEvents() call always happens after this, which will eventually call updateHeight()
-	},
-
-
 	/* Dragging (for events and external elements)
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -434,14 +341,6 @@ var AgendaView = FC.AgendaView = View.extend({
 	},
 
 
-	unrenderDrag: function() {
-		this.timeGrid.unrenderDrag();
-		if (this.dayGrid) {
-			this.dayGrid.unrenderDrag();
-		}
-	},
-
-
 	/* Selection
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -454,15 +353,6 @@ var AgendaView = FC.AgendaView = View.extend({
 		else if (this.dayGrid) {
 			this.dayGrid.renderSelection(span);
 		}
-	},
-
-
-	// Unrenders a visual indications of a selection
-	unrenderSelection: function() {
-		this.timeGrid.unrenderSelection();
-		if (this.dayGrid) {
-			this.dayGrid.unrenderSelection();
-		}
 	}
 
 });

+ 4 - 97
src/basic/BasicView.js

@@ -23,6 +23,7 @@ var BasicView = FC.BasicView = View.extend({
 
 	initialize: function() {
 		this.dayGrid = this.instantiateDayGrid();
+		this.addChild(this.dayGrid);
 
 		this.scroller = new Scroller({
 			overflowX: 'hidden',
@@ -110,16 +111,6 @@ var BasicView = FC.BasicView = View.extend({
 	},
 
 
-	renderBusinessHours: function() {
-		this.dayGrid.renderBusinessHours();
-	},
-
-
-	unrenderBusinessHours: function() {
-		this.dayGrid.unrenderBusinessHours();
-	},
-
-
 	// Builds the HTML skeleton for the view.
 	// The day-grid component will render inside of a container defined by this HTML.
 	renderSkeletonHtml: function() {
@@ -257,46 +248,6 @@ var BasicView = FC.BasicView = View.extend({
 	},
 
 
-	/* Hit Areas
-	------------------------------------------------------------------------------------------------------------------*/
-	// forward all hit-related method calls to dayGrid
-
-
-	hitsNeeded: function() {
-		this.dayGrid.hitsNeeded();
-	},
-
-
-	hitsNotNeeded: function() {
-		this.dayGrid.hitsNotNeeded();
-	},
-
-
-	prepareHits: function() {
-		this.dayGrid.prepareHits();
-	},
-
-
-	releaseHits: function() {
-		this.dayGrid.releaseHits();
-	},
-
-
-	queryHit: function(left, top) {
-		return this.dayGrid.queryHit(left, top);
-	},
-
-
-	getHitSpan: function(hit) {
-		return this.dayGrid.getHitSpan(hit);
-	},
-
-
-	getHitEl: function(hit) {
-		return this.dayGrid.getHitEl(hit);
-	},
-
-
 	/* Events
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -305,53 +256,9 @@ var BasicView = FC.BasicView = View.extend({
 	renderEvents: function(events) {
 		this.dayGrid.renderEvents(events);
 
-		this.updateHeight(); // must compensate for events that overflow the row
-	},
-
-
-	// Retrieves all segment objects that are rendered in the view
-	getEventSegs: function() {
-		return this.dayGrid.getEventSegs();
-	},
-
-
-	// Unrenders all event elements and clears internal segment data
-	unrenderEvents: function() {
-		this.dayGrid.unrenderEvents();
-
-		// we DON'T need to call updateHeight() because
-		// a renderEvents() call always happens after this, which will eventually call updateHeight()
-	},
-
-
-	/* Dragging (for both events and external elements)
-	------------------------------------------------------------------------------------------------------------------*/
-
-
-	// A returned value of `true` signals that a mock "helper" event has been rendered.
-	renderDrag: function(dropLocation, seg) {
-		return this.dayGrid.renderDrag(dropLocation, seg);
-	},
-
-
-	unrenderDrag: function() {
-		this.dayGrid.unrenderDrag();
-	},
-
-
-	/* Selection
-	------------------------------------------------------------------------------------------------------------------*/
-
-
-	// Renders a visual indication of a selection
-	renderSelection: function(span) {
-		this.dayGrid.renderSelection(span);
-	},
-
-
-	// Unrenders a visual indications of a selection
-	unrenderSelection: function() {
-		this.dayGrid.unrenderSelection();
+		// must compensate for events that overflow the row
+		// TODO: how will ChronoComponent handle this?
+		this.updateHeight();
 	}
 
 });

+ 107 - 20
src/common/ChronoComponent.js

@@ -1,6 +1,8 @@
 
 var ChronoComponent = Model.extend({
 
+	children: null,
+
 	el: null, // the view's containing element. set by Calendar(?)
 
 	// TODO: move below props to Options object
@@ -17,12 +19,19 @@ var ChronoComponent = Model.extend({
 	constructor: function() {
 		Model.call(this);
 
+		this.children = [];
+
 		this.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));
 		this.isRTL = this.opt('isRTL');
 		this.initThemingProps();
 	},
 
 
+	addChild: function(chronoComponent) {
+		this.children.push(chronoComponent);
+	},
+
+
 	// Options
 	// -----------------------------------------------------------------------------------------------------------------
 
@@ -121,29 +130,29 @@ var ChronoComponent = Model.extend({
 
 	// Renders a current time indicator at the given datetime
 	renderNowIndicator: function(date) {
-		// subclasses should implement
+		this.callChildren('renderNowIndicator', date);
 	},
 
 
 	// Undoes the rendering actions from renderNowIndicator
 	unrenderNowIndicator: function() {
-		// subclasses should implement
+		this.callChildren('unrenderNowIndicator');
 	},
 
 
 	// Business Hours
-	// ---------------------------------------------------------------------------------------------------------------*/
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Renders business-hours onto the view. Assumes updateSize has already been called.
 	renderBusinessHours: function() {
-		// subclasses should implement
+		this.callChildren('renderBusinessHours');
 	},
 
 
 	// Unrenders previously-rendered business-hours
 	unrenderBusinessHours: function() {
-		// subclasses should implement
+		this.callChildren('unrenderBusinessHours');
 	},
 
 
@@ -153,52 +162,114 @@ var ChronoComponent = Model.extend({
 
 	// Renders the events onto the view.
 	renderEvents: function(events) {
-		// subclasses should implement
+		this.callChildren('renderEvents', events);
 	},
 
 
 	// Removes event elements from the view.
 	unrenderEvents: function() {
-		// subclasses should implement
+		this.callChildren('unrenderEvents');
+
+		// we DON'T need to call updateHeight() because
+		// a renderEvents() call always happens after this, which will eventually call updateHeight()
+	},
+
+
+	// Retrieves all segment objects that are rendered in the view
+	getEventSegs: function() {
+		var children = this.children;
+		var segs = [];
+		var i;
+
+		for (i = 0; i < children.length; i++) {
+			segs.push.apply( // append
+				segs,
+				children[i].getEventSegs()
+			);
+		}
+
+		return segs;
 	},
 
 
 	// Drag-n-Drop Rendering (for both events and external elements)
-	// ---------------------------------------------------------------------------------------------------------------*/
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Renders a visual indication of a event or external-element drag over the given drop zone.
 	// If an external-element, seg will be `null`.
 	// Must return elements used for any mock events.
 	renderDrag: function(dropLocation, seg) {
-		// subclasses must implement
+		this.callChildren('renderDrag', dropLocation, seg);
 	},
 
 
 	// Unrenders a visual indication of an event or external-element being dragged.
 	unrenderDrag: function() {
-		// subclasses must implement
+		this.callChildren('unrenderDrag');
 	},
 
 
 	// Selection
-	// ---------------------------------------------------------------------------------------------------------------*/
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Renders a visual indication of the selection
 	renderSelection: function(span) {
-		// subclasses should implement
+		this.callChildren('renderSelection', span);
 	},
 
 
 	// Unrenders a visual indication of selection
 	unrenderSelection: function() {
-		// subclasses should implement
+		this.callChildren('unrenderSelection');
+	},
+
+
+	// Hit Areas
+	// ---------------------------------------------------------------------------------------------------------------
+
+
+	hitsNeeded: function() {
+		this.callChildren('hitsNeeded');
+	},
+
+
+	hitsNotNeeded: function() {
+		this.callChildren('hitsNotNeeded');
+	},
+
+
+	prepareHits: function() {
+		this.callChildren('prepareHits');
+	},
+
+
+	releaseHits: function() {
+		this.callChildren('releaseHits');
+	},
+
+
+	queryHit: function(left, top) {
+		var children = this.children;
+		var i;
+		var hit;
+
+		for (i = 0; i < children.length; i++) {
+			hit = children[i].queryHit(left, top);
+
+			if (hit) {
+				break;
+			}
+		}
+
+		return hit;
 	},
 
 
-	/* Event Drag-n-Drop
-	------------------------------------------------------------------------------------------------------------------*/
+
+	// Event Drag-n-Drop
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Computes if the given event is allowed to be dragged by the user
@@ -226,8 +297,8 @@ var ChronoComponent = Model.extend({
 	},
 
 
-	/* Event Resizing
-	------------------------------------------------------------------------------------------------------------------*/
+	// Event Resizing
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Computes if the given event is allowed to be resized from its starting edge
@@ -258,7 +329,7 @@ var ChronoComponent = Model.extend({
 
 
 	// Navigation
-	// ----------------------------------------------------------------------------------------------------------------*/
+	// ----------------------------------------------------------------------------------------------------------------
 
 
 	// Generates HTML for an anchor to another view into the calendar.
@@ -309,7 +380,7 @@ var ChronoComponent = Model.extend({
 
 
 	// Date Formatting Utils
-	// ---------------------------------------------------------------------------------------------------------------*/
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Utility for formatting a range. Accepts a range object, formatting string, and optional separator.
@@ -372,7 +443,7 @@ var ChronoComponent = Model.extend({
 
 
 	// Date Utils
-	// ---------------------------------------------------------------------------------------------------------------*/
+	// ---------------------------------------------------------------------------------------------------------------
 
 
 	// Returns the date range of the full days the given range visually appears to occupy.
@@ -410,6 +481,22 @@ var ChronoComponent = Model.extend({
 		var range = this.computeDayRange(event); // event is range-ish
 
 		return range.end.diff(range.start, 'days') > 1;
+	},
+
+
+	// Utils
+	// ---------------------------------------------------------------------------------------------------------------
+
+
+	callChildren: function(methodName) {
+		var args = Array.prototype.slice.call(arguments, 1);
+		var children = this.children;
+		var i, child;
+
+		for (i = 0; i < children.length; i++) {
+			child = children[i];
+			child[methodName].apply(child, args);
+		}
 	}
 
 });

+ 0 - 7
src/common/View.js

@@ -720,13 +720,6 @@ var View = FC.View = ChronoComponent.extend({
 	},
 
 
-	// Retrieves all the rendered segment objects for the view
-	getEventSegs: function() {
-		// subclasses must implement
-		return [];
-	},
-
-
 	/* Event Drag-n-Drop
 	------------------------------------------------------------------------------------------------------------------*/
 

+ 2 - 8
src/list/ListView.js

@@ -9,6 +9,8 @@ var ListView = View.extend({
 
 	initialize: function() {
 		this.grid = new ListViewGrid(this);
+		this.addChild(this.grid);
+
 		this.scroller = new Scroller({
 			overflowX: 'hidden',
 			overflowY: 'auto'
@@ -44,14 +46,6 @@ var ListView = View.extend({
 		this.grid.setRange(this.renderRange); // needs to process range-related options
 	},
 
-	renderEvents: function(events) {
-		this.grid.renderEvents(events);
-	},
-
-	unrenderEvents: function() {
-		this.grid.unrenderEvents();
-	},
-
 	isEventResizable: function(event) {
 		return false;
 	},