Getter and setter support for bindTo

This commit is contained in:
Frederic Junod
2013-10-30 15:18:07 +01:00
parent 0814b2c5c6
commit 03cc533cb3
2 changed files with 84 additions and 8 deletions
+10 -3
View File
@@ -35,9 +35,16 @@ var map = new ol.Map({
}); });
var projectionSelect = new ol.dom.Input(document.getElementById('projection')); var projectionSelect = new ol.dom.Input(document.getElementById('projection'));
projectionSelect.on('change:value', function() { projectionSelect.bindTo('value', mousePositionControl, 'projection')
mousePositionControl.setProjection(ol.proj.get(projectionSelect.getValue())); .transform(
}); function(code) {
// projectionSelect.value -> mousePositionControl.projection
return ol.proj.get(/** @type {string} */ (code));
},
function(projection) {
// mousePositionControl.projection -> projectionSelect.value
return projection.getCode();
});
var precisionInput = document.getElementById('precision'); var precisionInput = document.getElementById('precision');
precisionInput.addEventListener('change', function() { precisionInput.addEventListener('change', function() {
+74 -5
View File
@@ -11,6 +11,7 @@ goog.provide('ol.ObjectEventType');
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.events'); goog.require('goog.events');
goog.require('goog.events.EventTarget'); goog.require('goog.events.EventTarget');
goog.require('goog.functions');
goog.require('goog.object'); goog.require('goog.object');
@@ -22,6 +23,49 @@ ol.ObjectEventType = {
}; };
/**
* @constructor
* @param {ol.Object} target
* @param {string} key
* @todo stability experimental
*/
ol.ObjectAccessor = function(target, key) {
/**
* @type {ol.Object}
*/
this.target = target;
/**
* @type {string}
*/
this.key = key;
/**
* @type {function(?): ?}
*/
this.from = goog.functions.identity;
/**
* @type {function(?): ?}
*/
this.to = goog.functions.identity;
};
/**
* @param {function(?): ?} from A function that transforms the source value
* before it is set to the target.
* @param {function(?): ?} to A function that transforms the target value
* before it is set to the source.
*/
ol.ObjectAccessor.prototype.transform = function(from, to) {
this.from = from;
this.to = to;
};
/** /**
* @enum {string} * @enum {string}
*/ */
@@ -87,7 +131,7 @@ ol.Object.capitalize = function(str) {
/** /**
* @param {ol.Object} obj Object. * @param {ol.Object} obj Object.
* @return {Object.<string, {target: ol.Object, key: string}>} Accessors. * @return {Object.<string, ol.ObjectAccessor>} Accessors.
*/ */
ol.Object.getAccessors = function(obj) { ol.Object.getAccessors = function(obj) {
return obj[ol.ObjectProperty.ACCESSORS] || return obj[ol.ObjectProperty.ACCESSORS] ||
@@ -139,14 +183,35 @@ ol.Object.getSetterName = function(key) {
/** /**
* Binds a View to a Model. * The bindTo method allows you to set up a two-way binding between a
* `source` and `target` object. The method returns an
* ol.ObjectAccessor with a transform method that lets you transform
* values on the way from the source to the target and on the way back.
*
* For example, if you had two map views (sourceView and targetView)
* and you wanted the target view to have double the resolution of the
* source view, you could transform the resolution on the way to and
* from the target with the following:
*
* sourceView.bindTo('resolution', targetView)
* .transform(
* function(sourceResolution) {
* // from sourceView.resolution to targetView.resolution
* return 2 * sourceResolution;
* },
* function(targetResolution) {
* // from targetView.resolution to sourceView.resolution
* return targetResolution / 2;
* }
* );
*
* @param {string} key Key. * @param {string} key Key.
* @param {ol.Object} target Target. * @param {ol.Object} target Target.
* @param {string=} opt_targetKey Target key. * @param {string=} opt_targetKey Target key.
* @return {ol.ObjectAccessor}
* @todo stability experimental * @todo stability experimental
*/ */
ol.Object.prototype.bindTo = ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
function(key, target, opt_targetKey) {
var targetKey = opt_targetKey || key; var targetKey = opt_targetKey || key;
this.unbind(key); this.unbind(key);
var eventType = ol.Object.getChangeEventType(targetKey); var eventType = ol.Object.getChangeEventType(targetKey);
@@ -154,9 +219,11 @@ ol.Object.prototype.bindTo =
listeners[key] = goog.events.listen(target, eventType, function() { listeners[key] = goog.events.listen(target, eventType, function() {
this.notifyInternal_(key); this.notifyInternal_(key);
}, undefined, this); }, undefined, this);
var accessor = new ol.ObjectAccessor(target, targetKey);
var accessors = ol.Object.getAccessors(this); var accessors = ol.Object.getAccessors(this);
accessors[key] = {target: target, key: targetKey}; accessors[key] = accessor;
this.notifyInternal_(key); this.notifyInternal_(key);
return accessor;
}; };
@@ -179,6 +246,7 @@ ol.Object.prototype.get = function(key) {
} else { } else {
value = target.get(targetKey); value = target.get(targetKey);
} }
value = accessor.to(value);
} else if (this.values_.hasOwnProperty(key)) { } else if (this.values_.hasOwnProperty(key)) {
value = this.values_[key]; value = this.values_[key];
} }
@@ -289,6 +357,7 @@ ol.Object.prototype.set = function(key, value) {
var target = accessor.target; var target = accessor.target;
var targetKey = accessor.key; var targetKey = accessor.key;
var setterName = ol.Object.getSetterName(targetKey); var setterName = ol.Object.getSetterName(targetKey);
value = accessor.from(value);
if (target[setterName]) { if (target[setterName]) {
target[setterName](value); target[setterName](value);
} else { } else {