Bladeren bron

replace options triggering system with Model

Adam Shaw 8 jaren geleden
bovenliggende
commit
3cc4df7704
5 gewijzigde bestanden met toevoegingen van 37 en 92 verwijderingen
  1. 3 2
      src/Calendar.js
  2. 17 13
      src/Calendar.moment.js
  3. 10 71
      src/Calendar.options.js
  4. 6 6
      src/Calendar.render.js
  5. 1 0
      src/locale.js

+ 3 - 2
src/Calendar.js

@@ -417,12 +417,13 @@ var Calendar = FC.Calendar = Class.extend(EmitterMixin, {
 
 	publiclyTrigger: function(name, thisObj) {
 		var args = Array.prototype.slice.call(arguments, 2);
+		var optHandler = this.opt(name);
 
 		thisObj = thisObj || this.el[0];
 		this.triggerWith(name, thisObj, args); // Emitter's method
 
-		if (this.options[name]) {
-			return this.options[name].apply(thisObj, args);
+		if (optHandler) {
+			return optHandler.apply(thisObj, args);
 		}
 	}
 

+ 17 - 13
src/Calendar.moment.js

@@ -14,9 +14,13 @@ Calendar.mixin({
 
 		// Called immediately, and when any of the options change.
 		// Happens before any internal objects rebuild or rerender, because this is very core.
-		this.bindOptions([
-			'locale', 'monthNames', 'monthNamesShort', 'dayNames', 'dayNamesShort', 'firstDay', 'weekNumberCalculation'
-		], function(locale, monthNames, monthNamesShort, dayNames, dayNamesShort, firstDay, weekNumberCalculation) {
+		this.optionsModel.watch('buildingMomentLocale', [
+			'?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort',
+			'?firstDay', '?weekNumberCalculation'
+		], function(opts) {
+			var weekNumberCalculation = opts.weekNumberCalculation;
+			var firstDay = opts.firstDay;
+			var _week;
 
 			// normalize
 			if (weekNumberCalculation === 'iso') {
@@ -24,27 +28,27 @@ Calendar.mixin({
 			}
 
 			var localeData = createObject( // make a cheap copy
-				getMomentLocaleData(locale) // will fall back to en
+				getMomentLocaleData(opts.locale) // will fall back to en
 			);
 
-			if (monthNames) {
-				localeData._months = monthNames;
+			if (opts.monthNames) {
+				localeData._months = opts.monthNames;
 			}
-			if (monthNamesShort) {
-				localeData._monthsShort = monthNamesShort;
+			if (opts.monthNamesShort) {
+				localeData._monthsShort = opts.monthNamesShort;
 			}
-			if (dayNames) {
-				localeData._weekdays = dayNames;
+			if (opts.dayNames) {
+				localeData._weekdays = opts.dayNames;
 			}
-			if (dayNamesShort) {
-				localeData._weekdaysShort = dayNamesShort;
+			if (opts.dayNamesShort) {
+				localeData._weekdaysShort = opts.dayNamesShort;
 			}
 
 			if (firstDay == null && weekNumberCalculation === 'ISO') {
 				firstDay = 1;
 			}
 			if (firstDay != null) {
-				var _week = createObject(localeData._week); // _week: { dow: # }
+				_week = createObject(localeData._week); // _week: { dow: # }
 				_week.dow = firstDay;
 				localeData._week = _week;
 			}

+ 10 - 71
src/Calendar.options.js

@@ -7,13 +7,13 @@ Calendar.mixin({
 	localeDefaults: null, // option defaults related to current locale
 	overrides: null, // option overrides given to the fullCalendar constructor
 	dynamicOverrides: null, // options set with dynamic setter method. higher precedence than view overrides.
-	options: null, // all defaults combined with overrides
+	optionsModel: null, // all defaults combined with overrides
 
 
 	initOptionsInternals: function(overrides) {
 		this.overrides = $.extend({}, overrides); // make a copy
 		this.dynamicOverrides = {};
-		this.optionHandlers = {};
+		this.optionsModel = new Model();
 
 		this.populateOptionsHash();
 	},
@@ -25,7 +25,7 @@ Calendar.mixin({
 
 		if (typeof name === 'string') {
 			if (value === undefined) { // getter
-				return this.options[name];
+				return this.optionsModel.get(name);
 			}
 			else { // setter for individual option
 				newOptionHash = {};
@@ -41,7 +41,7 @@ Calendar.mixin({
 
 	// private getter
 	opt: function(name) {
-		return this.options[name];
+		return this.optionsModel.get(name);
 	},
 
 
@@ -96,6 +96,7 @@ Calendar.mixin({
 	populateOptionsHash: function() {
 		var locale, localeDefaults;
 		var isRTL, dirDefaults;
+		var rawOptions;
 
 		locale = firstDefined( // explicit locale option given?
 			this.dynamicOverrides.locale,
@@ -117,14 +118,17 @@ Calendar.mixin({
 
 		this.dirDefaults = dirDefaults;
 		this.localeDefaults = localeDefaults;
-		this.options = mergeOptions([ // merge defaults and overrides. lowest to highest precedence
+
+		rawOptions = mergeOptions([ // merge defaults and overrides. lowest to highest precedence
 			Calendar.defaults, // global defaults
 			dirDefaults,
 			localeDefaults,
 			this.overrides,
 			this.dynamicOverrides
 		]);
-		populateInstanceComputableOptions(this.options); // fill in gaps with computed options
+		populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options
+
+		this.optionsModel.reset(rawOptions);
 	},
 
 
@@ -138,71 +142,6 @@ Calendar.mixin({
 
 		this.viewSpecCache = {}; // the dynamic override invalidates the options in this cache, so just clear it
 		this.populateOptionsHash(); // this.options needs to be recomputed after the dynamic override
-
-		// trigger handlers after this.options has been updated
-		for (optionName in newOptionHash) {
-			this.triggerOptionHandlers(optionName); // recall bindOption/bindOptions
-		}
-	},
-
-
-	// Binding
-	// -----------------------------------------------------------------------------------------------------------------
-
-	// A map of option names to arrays of handler objects. Initialized to {} in Calendar.
-	// Format for a handler object:
-	// {
-	//   func // callback function to be called upon change
-	//   names // option names whose values should be given to func
-	// }
-	optionHandlers: null, 
-
-	// Calls handlerFunc immediately, and when the given option has changed.
-	// handlerFunc will be given the option value.
-	bindOption: function(optionName, handlerFunc) {
-		this.bindOptions([ optionName ], handlerFunc);
-	},
-
-	// Calls handlerFunc immediately, and when any of the given options change.
-	// handlerFunc will be given each option value as ordered function arguments.
-	bindOptions: function(optionNames, handlerFunc) {
-		var handlerObj = { func: handlerFunc, names: optionNames };
-		var i;
-
-		for (i = 0; i < optionNames.length; i++) {
-			this.registerOptionHandlerObj(optionNames[i], handlerObj);
-		}
-
-		this.triggerOptionHandlerObj(handlerObj);
-	},
-
-	// Puts the given handler object into the internal hash
-	registerOptionHandlerObj: function(optionName, handlerObj) {
-		(this.optionHandlers[optionName] || (this.optionHandlers[optionName] = []))
-			.push(handlerObj);
-	},
-
-	// Reports that the given option has changed, and calls all appropriate handlers.
-	triggerOptionHandlers: function(optionName) {
-		var handlerObjs = this.optionHandlers[optionName] || [];
-		var i;
-
-		for (i = 0; i < handlerObjs.length; i++) {
-			this.triggerOptionHandlerObj(handlerObjs[i]);
-		}
-	},
-
-	// Calls the callback for a specific handler object, passing in the appropriate arguments.
-	triggerOptionHandlerObj: function(handlerObj) {
-		var optionNames = handlerObj.names;
-		var optionValues = [];
-		var i;
-
-		for (i = 0; i < optionNames.length; i++) {
-			optionValues.push(this.options[optionNames[i]]);
-		}
-
-		handlerObj.func.apply(this, optionValues); // maintain the Calendar's `this` context
 	}
 
 });

+ 6 - 6
src/Calendar.render.js

@@ -48,16 +48,16 @@ Calendar.mixin({
 		});
 
 		// called immediately, and upon option change
-		this.bindOption('theme', function(theme) {
-			el.toggleClass('ui-widget', theme);
-			el.toggleClass('fc-unthemed', !theme);
+		this.optionsModel.watch('applyingThemeClasses', [ '?theme' ], function(opts) {
+			el.toggleClass('ui-widget', opts.theme);
+			el.toggleClass('fc-unthemed', !opts.theme);
 		});
 
 		// called immediately, and upon option change.
 		// HACK: locale often affects isRTL, so we explicitly listen to that too.
-		this.bindOptions([ 'isRTL', 'locale' ], function(isRTL) {
-			el.toggleClass('fc-ltr', !isRTL);
-			el.toggleClass('fc-rtl', isRTL);
+		this.optionsModel.watch('applyingDirClasses', [ '?isRTL', '?locale' ], function(opts) {
+			el.toggleClass('fc-ltr', !opts.isRTL);
+			el.toggleClass('fc-rtl', opts.isRTL);
 		});
 
 		this.contentEl = $("<div class='fc-view-container'/>").prependTo(el);

+ 1 - 0
src/locale.js

@@ -176,6 +176,7 @@ var instanceComputableOptions = {
 
 };
 
+// TODO: make these computable properties in optionsModel
 function populateInstanceComputableOptions(options) {
 	$.each(instanceComputableOptions, function(name, func) {
 		if (options[name] == null) {