Add beforechange event type and provide key with change events

If you know ahead of time that you only want to listen for changes for a specific property, the foo:change type events can be useful.  If you want to listen for changes on all properties, the change event becomes more useful if it provides information on what changed.  And the beforechange event allows listeners to access values before they change.
This commit is contained in:
Tim Schaub
2013-12-06 10:54:09 -07:00
parent d4f20192d4
commit 9d3a4e3c6c
2 changed files with 75 additions and 4 deletions

View File

@@ -10,6 +10,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.Event');
goog.require('goog.functions'); goog.require('goog.functions');
goog.require('goog.object'); goog.require('goog.object');
goog.require('ol.Observable'); goog.require('ol.Observable');
@@ -19,11 +20,34 @@ goog.require('ol.Observable');
* @enum {string} * @enum {string}
*/ */
ol.ObjectEventType = { ol.ObjectEventType = {
BEFORECHANGE: 'beforechange',
CHANGE: 'change' CHANGE: 'change'
}; };
/**
* Object representing a property change event.
*
* @param {string} type The event type.
* @param {string} key The property name.
* @extends {goog.events.Event}
* @constructor
*/
ol.ObjectEvent = function(type, key) {
goog.base(this, type);
/**
* The name of the property whose value is changing.
* @type {string}
*/
this.key = key;
};
goog.inherits(ol.ObjectEvent, goog.events.Event);
/** /**
* @constructor * @constructor
* @param {ol.Object} target * @param {ol.Object} target
@@ -331,7 +355,7 @@ ol.Object.prototype.notify = function(key) {
ol.Object.prototype.notifyInternal_ = function(key) { ol.Object.prototype.notifyInternal_ = function(key) {
var eventType = ol.Object.getChangeEventType(key); var eventType = ol.Object.getChangeEventType(key);
this.dispatchEvent(eventType); this.dispatchEvent(eventType);
this.dispatchEvent(ol.ObjectEventType.CHANGE); this.dispatchEvent(new ol.ObjectEvent(ol.ObjectEventType.CHANGE, key));
}; };
@@ -342,6 +366,7 @@ ol.Object.prototype.notifyInternal_ = function(key) {
* @todo stability experimental * @todo stability experimental
*/ */
ol.Object.prototype.set = function(key, value) { ol.Object.prototype.set = function(key, value) {
this.dispatchEvent(new ol.ObjectEvent(ol.ObjectEventType.BEFORECHANGE, key));
var accessors = ol.Object.getAccessors(this); var accessors = ol.Object.getAccessors(this);
if (accessors.hasOwnProperty(key)) { if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key]; var accessor = accessors[key];

View File

@@ -121,7 +121,11 @@ describe('ol.Object', function() {
it('dispatches generic change events to bound objects', function() { it('dispatches generic change events to bound objects', function() {
o.notify('k'); o.notify('k');
expect(listener2).to.be.called(); expect(listener2.calledOnce).to.be(true);
var args = listener2.firstCall.args;
expect(args).to.have.length(1);
var event = args[0];
expect(event.key).to.be('k');
}); });
it('dispatches events to bound objects', function() { it('dispatches events to bound objects', function() {
@@ -157,7 +161,25 @@ describe('ol.Object', function() {
it('dispatches generic change events to object', function() { it('dispatches generic change events to object', function() {
o.set('k', 1); o.set('k', 1);
expect(listener2).to.be.called(); expect(listener2.calledOnce).to.be(true);
var args = listener2.firstCall.args;
expect(args).to.have.length(1);
var event = args[0];
expect(event.key).to.be('k');
});
it('dispatches beforechange events to object', function() {
o.set('k', 1);
var oldValue;
var beforeListener = sinon.spy(function(event) {
oldValue = o2.get(event.key);
});
o.on('beforechange', beforeListener);
o.set('k', 2);
expect(beforeListener.calledOnce).to.be(true);
expect(oldValue).to.be(1);
}); });
it('dispatches events to bound object', function() { it('dispatches events to bound object', function() {
@@ -175,8 +197,32 @@ describe('ol.Object', function() {
it('dispatches generic change events to object bound to', function() { it('dispatches generic change events to object bound to', function() {
o2.set('k', 2); o2.set('k', 2);
expect(listener2).to.be.called(); expect(listener2.calledOnce).to.be(true);
var args = listener2.firstCall.args;
expect(args).to.have.length(1);
var event = args[0];
expect(event.key).to.be('k');
}); });
it('dispatches beforechange before changing bound objects', function() {
o2.set('k', 1);
var oldValue;
var beforeListener = sinon.spy(function(event) {
oldValue = o2.get(event.key);
});
o.on('beforechange', beforeListener);
o2.set('k', 2);
expect(beforeListener.calledOnce).to.be(true);
var args = listener2.firstCall.args;
expect(args).to.have.length(1);
var event = args[0];
expect(event.key).to.be('k');
expect(oldValue).to.be(1);
});
}); });
describe('bind', function() { describe('bind', function() {