From 5cf29d38e79bc079a5c87660a554fd3a06134c9e Mon Sep 17 00:00:00 2001 From: Benjamin Thurm Date: Tue, 12 May 2015 21:36:01 +0200 Subject: [PATCH] Dispose layer tree node event listeners. --- src/GeoExt/tree/LayerNode.js | 62 ++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/GeoExt/tree/LayerNode.js b/src/GeoExt/tree/LayerNode.js index c692987f9..5d6e36389 100644 --- a/src/GeoExt/tree/LayerNode.js +++ b/src/GeoExt/tree/LayerNode.js @@ -50,6 +50,15 @@ Ext.define('GeoExt.tree.LayerNode', { 'GeoExt.Version', 'GeoExt.tree.Util' ], + + /** + * Cached map this layer node's layer is associated with. + * @type {OpenLayers.Map} + * + * @private + */ + map: null, + /** * The init method is invoked after initComponent method has been run for * the client Component. It performs plugin initialization. @@ -81,8 +90,25 @@ Ext.define('GeoExt.tree.LayerNode', { scope: this }); - if (!layer.alwaysInRange && layer.map) { - layer.map.events.register('moveend', this, this.onMapMoveend); + if (layer.map) { + this.map = layer.map; + + // Triggers disposal of event listeners if the removed layer maps + // to this plugins layer node. + // TODO: Find a better way to link into lifecycle of the layer node + // to dispose event listeners. See: + // https://github.com/geoext/geoext2/pull/357 + this.map.events.on({ + 'removelayer': this.onMapRemovelayer, + scope: this + }); + } + + if (!layer.alwaysInRange && this.map) { + this.map.events.on({ + 'moveend': this.onMapMoveend, + scope: this + }); } GeoExt.tree.Util.enforceOneLayerVisible(this.target); @@ -114,6 +140,38 @@ Ext.define('GeoExt.tree.LayerNode', { } }, + /** + * Disposes event handlers that have been added during initialization of plugin. + * TODO: Add tests to make sure this works as expected. + * + * @private + */ + onMapRemovelayer: function(evt) { + var target = this.target, + layer = target.get('layer'); + + if (evt.layer !== layer) { + return; + } + + target.un('afteredit', this.onAfterEdit, this); + + layer.events.un({ + 'visibilitychanged': this.onLayerVisibilityChanged, + scope: this + }); + + this.map.events.un({ + 'removelayer': this.onMapRemovelayer, + 'moveend': this.onMapMoveend, + scope: this + }); + + this.map = null; + + return true; + }, + /** * handler for map moveend events to determine if node should be * disabled or enabled