From 9d3a4e3c6cad6a60b3e3ba2d292d0e49188ccd33 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Fri, 6 Dec 2013 10:54:09 -0700 Subject: [PATCH] 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. --- src/ol/object.js | 27 ++++++++++++++++++- test/spec/ol/object.test.js | 52 ++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/ol/object.js b/src/ol/object.js index 4bca4e75ca..cbef3af6c6 100644 --- a/src/ol/object.js +++ b/src/ol/object.js @@ -10,6 +10,7 @@ goog.provide('ol.ObjectEventType'); goog.require('goog.array'); goog.require('goog.events'); +goog.require('goog.events.Event'); goog.require('goog.functions'); goog.require('goog.object'); goog.require('ol.Observable'); @@ -19,11 +20,34 @@ goog.require('ol.Observable'); * @enum {string} */ ol.ObjectEventType = { + BEFORECHANGE: 'beforechange', 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 * @param {ol.Object} target @@ -331,7 +355,7 @@ ol.Object.prototype.notify = function(key) { ol.Object.prototype.notifyInternal_ = function(key) { var eventType = ol.Object.getChangeEventType(key); 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 */ ol.Object.prototype.set = function(key, value) { + this.dispatchEvent(new ol.ObjectEvent(ol.ObjectEventType.BEFORECHANGE, key)); var accessors = ol.Object.getAccessors(this); if (accessors.hasOwnProperty(key)) { var accessor = accessors[key]; diff --git a/test/spec/ol/object.test.js b/test/spec/ol/object.test.js index 1c59d6f273..9a53c6d40f 100644 --- a/test/spec/ol/object.test.js +++ b/test/spec/ol/object.test.js @@ -121,7 +121,11 @@ describe('ol.Object', function() { it('dispatches generic change events to bound objects', function() { 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() { @@ -157,7 +161,25 @@ describe('ol.Object', function() { it('dispatches generic change events to object', function() { 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() { @@ -175,8 +197,32 @@ describe('ol.Object', function() { it('dispatches generic change events to object bound to', function() { 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() {