[Commits] r609 - in sandbox/opengeo/geoexplorer: lib/GeoExt/data tests/lib/GeoExt/data
commits at geoext.org
commits at geoext.org
Wed May 6 21:24:42 CEST 2009
Author: sbenthall
Date: 2009-05-06 21:24:42 +0200 (Wed, 06 May 2009)
New Revision: 609
Modified:
sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js
sandbox/opengeo/geoexplorer/tests/lib/GeoExt/data/LayerStore.html
Log:
bringing sandbox LayerStore and LayerStore tests in line with trunk (see r370 and r451)
Modified: sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js
===================================================================
--- sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js 2009-05-06 18:16:33 UTC (rev 608)
+++ sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js 2009-05-06 19:24:42 UTC (rev 609)
@@ -43,7 +43,7 @@
map: null,
/**
- * Property: reader
+ * APIProperty: reader
* {<GeoExt.data.LayerReader>} The reader used to get
* <GeoExt.data.LayerRecord> objects from {OpenLayers.Layer}
* objects.
@@ -60,31 +60,39 @@
* map - {OpenLayers.Map|<GeoExt.MapPanel>} map to sync the layer store
* with.
* layers - {Array(OpenLayers.Layer)} Layers that will be added to the
- * layer store (and the map, because we are already syncing).
- * recordType - {<GeoExt.data.LayerRecord>} If provided, a custom layer
- * record type with additional fields will be used. Default fields for
- * every layer record are {OpenLayers.Layer} layer and {String} title.
+ * store (and the map, depending on the value of the initDir option).
+ * fields - {Array} If provided a custom layer record type with additional
+ * fields will be used. Default fields for every layer record are
+ * {OpenLayers.Layer} layer and {String} title. The value of this
+ * option is either a field definition objects as passed to the
+ * GeoExt.data.LayerRecord.create function or a
+ * {<GeoExt.data.LayerRecord>} constructor created using
+ * GeoExt.data.LayerRecord.create.
+ * initDir - {Number} Bitfields specifying the direction to use for the
+ * initial sync between the map and the store, if set to 0 then no
+ * initial sync is done. Defaults to
+ * <GeoExt.data.LayerStore.MAP_TO_STORE>|<GeoExt.data.LayerStore.STORE_TO_MAP>.
*/
constructor: function(config) {
config = config || {};
config.reader = config.reader ||
- new GeoExt.data.LayerReader({}, config.recordType);
+ new GeoExt.data.LayerReader({}, config.fields);
+ delete config.fields;
+ // "map" option
var map = config.map instanceof GeoExt.MapPanel ?
config.map.map : config.map;
delete config.map;
+ // "layers" option - is an alias to "data" option
+ if(config.layers) {
+ config.data = config.layers;
+ }
+ delete config.layers;
+ // "initDir" option
+ var options = {initDir: config.initDir};
+ delete config.initDir;
arguments.callee.superclass.constructor.call(this, config);
if(map) {
- // create a snapshop of the map's layers
- var layers = map.layers;
- var layer;
- // walk through the layers snapshot and add layers to the store
- for(var i=0; i<layers.length; ++i) {
- layer = layers[i];
- this.add((this.reader.readRecords([layer])).records);
- }
-
- this.bind(map);
- config.layers && map.addLayers(config.layers);
+ this.bind(map, options);
}
},
@@ -95,26 +103,54 @@
*
* Parameters:
* map - {OpenLayers.Map} The map instance.
+ * options - {Object}
+ *
+ * Valid config options:
+ * initDir - {Number} Bitfields specifying the direction to use for the
+ * initial sync between the map and the store, if set to 0 then no
+ * initial sync is done. Defaults to
+ * <GeoExt.data.LayerStore.MAP_TO_STORE>|<GeoExt.data.LayerStore.STORE_TO_MAP>.
*/
- bind: function(map) {
- if(!this.map) {
- this.map = map;
- map.events.on({
- "changelayer": this.onChangeLayer,
- "addlayer": this.onAddLayer,
- "removelayer": this.onRemoveLayer,
- scope: this
- });
- this.on({
- "add": this.onAdd,
- "remove": this.onRemove,
- scope: this
- });
- this.data.on({
- "replace" : this.onReplace,
- scope: this
- });
+ bind: function(map, options) {
+ if(this.map) {
+ // already bound
+ return;
}
+ this.map = map;
+ options = options || {};
+
+ var initDir = options.initDir;
+ if(options.initDir == undefined) {
+ initDir = GeoExt.data.LayerStore.MAP_TO_STORE |
+ GeoExt.data.LayerStore.STORE_TO_MAP;
+ }
+
+ // create a snapshot of the map's layers
+ var layers = map.layers.slice(0);
+
+ if(initDir & GeoExt.data.LayerStore.STORE_TO_MAP) {
+ var records = this.getRange();
+ for(var i=records.length - 1; i>=0; i--) {
+ this.map.addLayer(records[i].get("layer"));
+ }
+ }
+ if(initDir & GeoExt.data.LayerStore.MAP_TO_STORE) {
+ this.loadData(layers, true);
+ }
+
+ map.events.on({
+ "changelayer": this.onChangeLayer,
+ "addlayer": this.onAddLayer,
+ "removelayer": this.onRemoveLayer,
+ scope: this
+ });
+ this.on({
+ "load": this.onLoad,
+ "clear": this.onClear,
+ "add": this.onAdd,
+ "remove": this.onRemove,
+ scope: this
+ });
},
/**
@@ -129,15 +165,11 @@
"removelayer": this.onRemoveLayer,
scope: this
});
- this.un({
- "add": this.onAdd,
- "remove": this.onRemove,
- scope: this
- });
- this.data.un({
- "replace" : this.onReplace,
- scope: this
- });
+ this.un("load", this.onLoad, this);
+ this.un("clear", this.onClear, this);
+ this.un("add", this.onAdd, this);
+ this.un("remove", this.onRemove, this);
+
this.map = null;
}
},
@@ -184,7 +216,7 @@
if(!this._adding) {
var layer = evt.layer;
this._adding = true;
- this.add((this.reader.readRecords([layer])).records);
+ this.loadData([layer], true);
delete this._adding;
}
},
@@ -206,6 +238,55 @@
},
/**
+ * Method: onLoad
+ * Handler for a store's load event
+ *
+ * Parameters:
+ * store - {<Ext.data.Store>}
+ * records - {Array(Ext.data.Record)}
+ * options - {Object}
+ */
+ onLoad: function(store, records, options) {
+ if (!Ext.isArray(records)) {
+ records = [records];
+ }
+ if (options && !options.add) {
+ this._removing = true;
+ for (var i = this.map.layers.length - 1; i >= 0; i--) {
+ this.map.removeLayer(this.map.layers[i]);
+ }
+ delete this._removing;
+
+ // layers has already been added to map on "add" event
+ var len = records.length;
+ if (len > 0) {
+ var layers = new Array(len);
+ for (var j = 0; j < len; j++) {
+ layers[j] = records[j].get("layer");
+ }
+ this._adding = true;
+ this.map.addLayers(layers);
+ delete this._adding;
+ }
+ }
+ },
+
+ /**
+ * Method: onClear
+ * Handler for a store's clear event
+ *
+ * Parameters:
+ * store - {<Ext.data.Store>}
+ */
+ onClear: function(store) {
+ this._removing = true;
+ for (var i = this.map.layers.length - 1; i >= 0; i--) {
+ this.map.removeLayer(this.map.layers[i]);
+ }
+ delete this._removing;
+ },
+
+ /**
* Method: onAdd
* Handler for a store's add event
*
@@ -240,23 +321,13 @@
*/
onRemove: function(store, record, index){
if(!this._removing) {
- this._removing = true;
- this.map.removeLayer(record.get("layer"));
- delete this._removing;
+ var layer = record.get("layer");
+ if (this.map.getLayer(layer.id) != null) {
+ this._removing = true;
+ this.map.removeLayer(record.get("layer"));
+ delete this._removing;
+ }
}
- },
-
- /**
- * Method: onReplace
- * Handler for a store's data collections' replace event
- *
- * Parameters:
- * key - {String}
- * oldRecord - {Object} In this case, a record that has been replaced.
- * newRecord - {Object} In this case, a record that is replacing oldRecord.
- */
- onReplace: function(key, oldRecord, newRecord){
- this.remove(oldRecord);
}
};
@@ -281,3 +352,17 @@
Ext.data.Store,
GeoExt.data.LayerStoreMixin
);
+
+/**
+ * Constant: GeoExt.data.LayerStore.MAP_TO_STORE
+ * {Integer} Constant used to make the store be automatically updated
+ * when changes occur in the map.
+ */
+GeoExt.data.LayerStore.MAP_TO_STORE = 1;
+
+/**
+ * Constant: GeoExt.data.LayerStore.STORE_TO_MAP
+ * {Integer} Constant used to make the map be automatically updated
+ * when changes occur in the store.
+ */
+GeoExt.data.LayerStore.STORE_TO_MAP = 2;
Modified: sandbox/opengeo/geoexplorer/tests/lib/GeoExt/data/LayerStore.html
===================================================================
--- sandbox/opengeo/geoexplorer/tests/lib/GeoExt/data/LayerStore.html 2009-05-06 18:16:33 UTC (rev 608)
+++ sandbox/opengeo/geoexplorer/tests/lib/GeoExt/data/LayerStore.html 2009-05-06 19:24:42 UTC (rev 609)
@@ -33,9 +33,9 @@
}
function test_constructor(t) {
- t.plan(3);
+ t.plan(5);
- var store, reader, map;
+ var store, reader, map, fields;
store = new GeoExt.data.LayerStore();
t.ok(store.reader instanceof GeoExt.data.LayerReader,
@@ -50,6 +50,16 @@
store = new GeoExt.data.LayerStore({map: map});
t.ok(store.map == map,
"ctor sets the passed map in the instance");
+
+ fields = [{name: "foo"}];
+ store = new GeoExt.data.LayerStore({fields: fields});
+ t.eq(store.reader.recordType.prototype.fields.items[2].name, "foo",
+ "ctor creates a reader from array of field definitions with expected field in recordType prototype");
+
+ fields = GeoExt.data.LayerRecord.create([{name: "foo"}]);
+ store = new GeoExt.data.LayerStore({fields: fields});
+ t.eq(store.reader.recordType.prototype.fields.items[2].name, "foo",
+ "ctor creates a reader from layer record constructor with expected field in recordType prototype");
}
function test_layerstore(t) {
@@ -73,10 +83,93 @@
t.eq(map.layers.length,1,"Adding layer to MapPanel's LayerStore adds only one layer to map");
t.eq(mapPanel.layers.getCount(),1,"Adding layers to MapPanel's LayerStore does not create duplicate layers");
}
+
+ function test_load_clear(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map("mappanel");
+ var store = new GeoExt.data.LayerStore({
+ map: map
+ });
+
+ store.loadData([
+ new OpenLayers.Layer.Vector(),
+ new OpenLayers.Layer.Vector()
+ ]);
+ t.eq(map.layers.length, 2, "loading the store with two records adds two layers to the map");
+
+ store.removeAll();
+ t.eq(map.layers.length, 0, "clearing the store removes all layers from map");
+ }
+ function test_bind_unbind(t) {
+ t.plan(28);
+
+ var map = new OpenLayers.Map("mappanel");
+ var store = new GeoExt.data.LayerStore();
+ var layers = [new OpenLayers.Layer.Vector("Foo layer"),
+ new OpenLayers.Layer.Vector("Bar layer")];
+ var records = [
+ new GeoExt.data.LayerRecord({
+ layer: new OpenLayers.Layer.Vector("Foo record")}),
+ new GeoExt.data.LayerRecord({
+ layer: new OpenLayers.Layer.Vector("Bar record")})
+ ];
+
+ var reinit_test_data = function () {
+ // unbind store
+ store.unbind();
+
+ // remove all existing records and layers
+ store.removeAll();
+ for (var i=map.layers.length - 1; i>=0; i--) {
+ map.removeLayer(map.layers[i]);
+ }
+ t.eq(map.layers.length, 0, "there is no more layers in the map");
+ t.eq(store.getCount(), 0, "there is no more records in the store");
+
+ // add testing data to store and map
+ store.add(records);
+ map.addLayers(layers);
+ t.eq(map.layers.length, 2, "initial layers are loaded in the map");
+ t.eq(store.getCount(), 2, "initial records are loaded in the store");
+ };
+
+ // test store to map synchronization
+ reinit_test_data();
+ store.bind(map, {initDir: GeoExt.data.LayerStore.STORE_TO_MAP});
+ t.eq(map.layers.length, 4, "initial records are synchronized to map");
+ t.eq(store.getCount(), 2, "initial layers are not synchronized to store");
+ map.removeLayer(layers[0]);
+ t.eq(map.layers.length, 3, "removing layer not present in store has been well removed");
+ t.eq(store.getCount(), 2, "nothing to remove in store when removing layer not present in store");
+
+ // test map to store synchronization
+ reinit_test_data();
+ store.bind(map, {initDir: GeoExt.data.LayerStore.MAP_TO_STORE});
+ t.eq(map.layers.length, 2, "initial records are not synchronized to map");
+ t.eq(store.getCount(), 4, "initial layers are synchronized to store");
+ store.remove(records[0]);
+ t.eq(store.getCount(), 3, "removing record not present in map has been well removed");
+ t.eq(map.layers.length, 2, "nothing to remove in map when removing record not present in map");
+
+ // test both synchronization
+ reinit_test_data();
+ store.bind(map, {initDir: GeoExt.data.LayerStore.MAP_TO_STORE |
+ GeoExt.data.LayerStore.STORE_TO_MAP});
+ t.eq(map.layers.length, 4, "initial records are synchronized to map");
+ t.eq(store.getCount(), 4, "initial layers are synchronized to store");
+
+ // test no synchronization
+ reinit_test_data();
+ store.bind(map, {initDir: 0});
+ t.eq(map.layers.length, 2, "initial records are not synchronized to map");
+ t.eq(store.getCount(), 2, "initial layers are not synchronized to store");
+ }
+
function test_add_remove(t) {
- t.plan(3);
+ t.plan(2);
var map = new OpenLayers.Map("mappanel");
var store = new GeoExt.data.LayerStore({
@@ -91,14 +184,7 @@
store.remove(record);
t.eq(store.getCount(), 0, "removing a single record from the store removes one record");
-
- //test adding a record with the same id
- store.add([record]);
- store.add(store.getAt(0).copy());
- t.eq(map.layers.length,store.getCount(),"number of OpenLayers map layers equals number of records after adding record with same id");
-
-
}
function test_reorder(t) {
More information about the Commits
mailing list