Remove 2-way binding from objects

This commit is contained in:
Tim Schaub
2015-04-02 15:37:53 +02:00
parent 600b76e9a2
commit f42c0cb0aa
6 changed files with 17 additions and 987 deletions
+2 -2
View File
@@ -170,7 +170,7 @@ ol.control.OverviewMap.prototype.setMap = function(map) {
// if no layers were set for the overviewmap map, then bind with
// those in the main map
if (this.ovmap_.getLayers().getLength() === 0) {
this.ovmap_.bindTo(ol.MapProperty.LAYERGROUP, map);
this.ovmap_.setLayerGroup(map.getLayerGroup());
}
// bind current map view, or any new one
@@ -202,7 +202,7 @@ ol.control.OverviewMap.prototype.bindView_ = function() {
// FIXME - the overviewmap view rotation currently follows the one used
// by the main map view. We could support box rotation instead. The choice
// between the 2 modes would be made in a single option
this.ovmap_.getView().bindTo(ol.ViewProperty.ROTATION, view);
// this.ovmap_.getView().bindTo(ol.ViewProperty.ROTATION, view);
};
-149
View File
@@ -1,149 +0,0 @@
goog.provide('ol.dom.Input');
goog.provide('ol.dom.InputProperty');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.Object');
/**
* @enum {string}
*/
ol.dom.InputProperty = {
VALUE: 'value',
CHECKED: 'checked'
};
/**
* @classdesc
* Helper class for binding HTML input to an {@link ol.Object}.
*
* Example:
*
* // bind a checkbox with id 'visible' to a layer's visibility
* var visible = new ol.dom.Input(document.getElementById('visible'));
* visible.bindTo('checked', layer, 'visible');
*
* @constructor
* @extends {ol.Object}
* @param {Element} target Target element.
* @api
*/
ol.dom.Input = function(target) {
goog.base(this);
/**
* @private
* @type {HTMLInputElement}
*/
this.target_ = /** @type {HTMLInputElement} */ (target);
goog.events.listen(this.target_,
[goog.events.EventType.CHANGE, goog.events.EventType.INPUT],
this.handleInputChanged_, false, this);
goog.events.listen(this,
ol.Object.getChangeEventType(ol.dom.InputProperty.VALUE),
this.handleValueChanged_, false, this);
goog.events.listen(this,
ol.Object.getChangeEventType(ol.dom.InputProperty.CHECKED),
this.handleCheckedChanged_, false, this);
};
goog.inherits(ol.dom.Input, ol.Object);
/**
* If the input is a checkbox, return whether or not the checkbox is checked.
* @return {boolean|undefined} The checked state of the Input.
* @observable
* @api
*/
ol.dom.Input.prototype.getChecked = function() {
return /** @type {boolean} */ (this.get(ol.dom.InputProperty.CHECKED));
};
goog.exportProperty(
ol.dom.Input.prototype,
'getChecked',
ol.dom.Input.prototype.getChecked);
/**
* Get the value of the input.
* @return {string|undefined} The value of the Input.
* @observable
* @api
*/
ol.dom.Input.prototype.getValue = function() {
return /** @type {string} */ (this.get(ol.dom.InputProperty.VALUE));
};
goog.exportProperty(
ol.dom.Input.prototype,
'getValue',
ol.dom.Input.prototype.getValue);
/**
* Sets the value of the input.
* @param {string} value The value of the Input.
* @observable
* @api
*/
ol.dom.Input.prototype.setValue = function(value) {
this.set(ol.dom.InputProperty.VALUE, value);
};
goog.exportProperty(
ol.dom.Input.prototype,
'setValue',
ol.dom.Input.prototype.setValue);
/**
* Set whether or not a checkbox is checked.
* @param {boolean} checked The checked state of the Input.
* @observable
* @api
*/
ol.dom.Input.prototype.setChecked = function(checked) {
this.set(ol.dom.InputProperty.CHECKED, checked);
};
goog.exportProperty(
ol.dom.Input.prototype,
'setChecked',
ol.dom.Input.prototype.setChecked);
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.dom.Input.prototype.handleInputChanged_ = function(browserEvent) {
goog.asserts.assert(browserEvent.currentTarget == this.target_,
'currentTarget should be the same as this.target_');
var target = this.target_;
if (target.type === 'checkbox' || target.type === 'radio') {
this.setChecked(target.checked);
} else {
this.setValue(target.value);
}
};
/**
* @param {goog.events.Event} event Change event.
* @private
*/
ol.dom.Input.prototype.handleCheckedChanged_ = function(event) {
this.target_.checked = /** @type {boolean} */ (this.getChecked());
};
/**
* @param {goog.events.Event} event Change event.
* @private
*/
ol.dom.Input.prototype.handleValueChanged_ = function(event) {
this.target_.value = /** @type {string} */ (this.getValue());
};
+5 -273
View File
@@ -10,9 +10,7 @@ goog.provide('ol.ObjectEventType');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.functions');
goog.require('goog.object');
goog.require('goog.string');
goog.require('ol.Observable');
@@ -64,63 +62,6 @@ goog.inherits(ol.ObjectEvent, goog.events.Event);
/**
* @constructor
* @param {ol.Object} source Source object.
* @param {ol.Object} target Target object.
* @param {string} sourceKey Source key.
* @param {string} targetKey Target key.
*/
ol.ObjectAccessor = function(source, target, sourceKey, targetKey) {
/**
* @type {ol.Object}
*/
this.source = source;
/**
* @type {ol.Object}
*/
this.target = target;
/**
* @type {string}
*/
this.sourceKey = sourceKey;
/**
* @type {string}
*/
this.targetKey = targetKey;
/**
* @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.
* @api
*/
ol.ObjectAccessor.prototype.transform = function(from, to) {
var oldValue = ol.Object.getKeyValue_(this.source, this.sourceKey);
this.from = from;
this.to = to;
this.source.notify(this.sourceKey, oldValue);
};
/**
* @classdesc
* Abstract base class; normally only used for creating subclasses and not
@@ -157,12 +98,6 @@ ol.ObjectAccessor.prototype.transform = function(from, to) {
* first will be a `hasOwnProperty`; the second will appear in
* `getProperties()`. Only the second is observable.
*
* The observable properties also implement a form of Key Value Observing.
* Two objects can be bound together such that a change in one will
* automatically be reflected in the other. See `bindTo` method for more
* details, and see {@link ol.dom.Input} for the specific case of binding an
* object with an HTML element.
*
* Properties can be deleted by using the unset method. E.g.
* object.unset('foo').
*
@@ -187,18 +122,6 @@ ol.Object = function(opt_values) {
*/
this.values_ = {};
/**
* @private
* @type {Object.<string, ol.ObjectAccessor>}
*/
this.accessors_ = {};
/**
* @private
* @type {Object.<string, goog.events.Key>}
*/
this.listeners_ = {};
if (goog.isDef(opt_values)) {
this.setProperties(opt_values);
}
@@ -213,20 +136,6 @@ goog.inherits(ol.Object, ol.Observable);
ol.Object.changeEventTypeCache_ = {};
/**
* @private
* @type {Object.<string, string>}
*/
ol.Object.getterNameCache_ = {};
/**
* @private
* @type {Object.<string, string>}
*/
ol.Object.setterNameCache_ = {};
/**
* @param {string} key Key name.
* @return {string} Change name.
@@ -238,116 +147,6 @@ ol.Object.getChangeEventType = function(key) {
};
/**
* @param {string} key String.
* @return {string} Getter name.
*/
ol.Object.getGetterName = function(key) {
return ol.Object.getterNameCache_.hasOwnProperty(key) ?
ol.Object.getterNameCache_[key] :
(ol.Object.getterNameCache_[key] = 'get' + goog.string.capitalize(key));
};
/**
* @param {string} key String.
* @return {string} Setter name.
*/
ol.Object.getSetterName = function(key) {
return ol.Object.setterNameCache_.hasOwnProperty(key) ?
ol.Object.setterNameCache_[key] :
(ol.Object.setterNameCache_[key] = 'set' + goog.string.capitalize(key));
};
/**
* Get the value for an object and a key. Use the getter (`getX`) if it exists,
* otherwise use the generic `get` function.
* @param {ol.Object} obj Object.
* @param {string} key Key;
* @return {*} Value;
* @private
*/
ol.Object.getKeyValue_ = function(obj, key) {
var getterName = ol.Object.getGetterName(key);
var getter = /** @type {function(): *|undefined} */
(/** @type {Object} */ (obj)[getterName]);
return goog.isDef(getter) ? getter.call(obj) : obj.get(key);
};
/**
* Set the value for an object and a key. Use the setter (`setX`) if it exists,
* otherwise use the generic `set` function.
* @param {ol.Object} obj Object.
* @param {string} key Key.
* @param {*} value Value.
* @private
*/
ol.Object.setKeyValue_ = function(obj, key, value) {
var setterName = ol.Object.getSetterName(key);
var setter = /** @type {function(*)|undefined} */
(/** @type {Object} */ (obj)[setterName]);
if (goog.isDef(setter)) {
setter.call(obj, value);
} else {
obj.set(key, value);
}
};
/**
* The bindTo method allows you to set up a two-way binding between a
* `source` and `target` object. The method returns an object with a
* `transform` method that you can use to provide `from` and `to`
* functions to 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 name.
* @param {ol.Object} target Target.
* @param {string=} opt_targetKey Target key.
* @return {ol.ObjectAccessor}
* @api
*/
ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
var targetKey = opt_targetKey || key;
this.unbind(key);
// listen for change:targetkey events
var eventType = ol.Object.getChangeEventType(targetKey);
this.listeners_[key] = goog.events.listen(target, eventType,
/**
* @param {ol.ObjectEvent} e Event.
* @this {ol.Object}
*/
function(e) {
this.notify(key, e.oldValue);
}, undefined, this);
var accessor = new ol.ObjectAccessor(this, target, key, targetKey);
this.accessors_[key] = accessor;
this.notify(key, this.values_[key]);
return accessor;
};
/**
* Gets a value.
* @param {string} key Key name.
@@ -356,12 +155,7 @@ ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
*/
ol.Object.prototype.get = function(key) {
var value;
var accessors = this.accessors_;
if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key];
value = ol.Object.getKeyValue_(accessor.target, accessor.targetKey);
value = accessor.to(value);
} else if (this.values_.hasOwnProperty(key)) {
if (this.values_.hasOwnProperty(key)) {
value = this.values_[key];
}
return value;
@@ -374,29 +168,7 @@ ol.Object.prototype.get = function(key) {
* @api stable
*/
ol.Object.prototype.getKeys = function() {
var accessors = this.accessors_;
var keysObject;
if (goog.object.isEmpty(this.values_)) {
if (goog.object.isEmpty(accessors)) {
return [];
} else {
keysObject = accessors;
}
} else {
if (goog.object.isEmpty(accessors)) {
keysObject = this.values_;
} else {
keysObject = {};
var key;
for (key in this.values_) {
keysObject[key] = true;
}
for (key in accessors) {
keysObject[key] = true;
}
}
}
return goog.object.getKeys(keysObject);
return goog.object.getKeys(this.values_);
};
@@ -411,9 +183,6 @@ ol.Object.prototype.getProperties = function() {
for (key in this.values_) {
properties[key] = this.values_[key];
}
for (key in this.accessors_) {
properties[key] = this.get(key);
}
return properties;
};
@@ -438,16 +207,9 @@ ol.Object.prototype.notify = function(key, oldValue) {
* @api stable
*/
ol.Object.prototype.set = function(key, value) {
var accessors = this.accessors_;
if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key];
value = accessor.from(value);
ol.Object.setKeyValue_(accessor.target, accessor.targetKey, value);
} else {
var oldValue = this.values_[key];
this.values_[key] = value;
this.notify(key, oldValue);
}
var oldValue = this.values_[key];
this.values_[key] = value;
this.notify(key, oldValue);
};
@@ -465,36 +227,6 @@ ol.Object.prototype.setProperties = function(values) {
};
/**
* Removes a binding. Unbinding will set the unbound property to the current
* value. The object will not be notified, as the value has not changed.
* @param {string} key Key name.
* @api
*/
ol.Object.prototype.unbind = function(key) {
var listeners = this.listeners_;
var listener = listeners[key];
if (listener) {
delete listeners[key];
goog.events.unlistenByKey(listener);
var value = this.get(key);
delete this.accessors_[key];
this.values_[key] = value;
}
};
/**
* Removes all bindings.
* @api
*/
ol.Object.prototype.unbindAll = function() {
for (var key in this.listeners_) {
this.unbind(key);
}
};
/**
* Unsets a property.
* @param {string} key Key name.