[Commits] r207 - in sandbox/elemoine/playground: lib lib/GeoExt/data tests/data

commits at geoext.org commits at geoext.org
Sat Feb 21 00:53:06 CET 2009


Author: elemoine
Date: 2009-02-21 00:53:05 +0100 (Sat, 21 Feb 2009)
New Revision: 207

Added:
   sandbox/elemoine/playground/lib/GeoExt/data/RecordLayerMediator.js
Modified:
   sandbox/elemoine/playground/lib/GeoExt.js
   sandbox/elemoine/playground/lib/GeoExt/data/FeatureStoreMediator.js
   sandbox/elemoine/playground/lib/GeoExt/data/LayerStoreMediator.js
   sandbox/elemoine/playground/tests/data/LayerStoreMediator.html
Log:
extend LayerStoreMediator to support layer-to-store sync as well as store-to-layer sync


Modified: sandbox/elemoine/playground/lib/GeoExt/data/FeatureStoreMediator.js
===================================================================
--- sandbox/elemoine/playground/lib/GeoExt/data/FeatureStoreMediator.js	2009-02-19 23:00:48 UTC (rev 206)
+++ sandbox/elemoine/playground/lib/GeoExt/data/FeatureStoreMediator.js	2009-02-20 23:53:05 UTC (rev 207)
@@ -25,8 +25,15 @@
 
 /**
  * Class: GeoExt.data.FeatureStoreMediator
- * This class is to be used when one wants to insert features in a store.
+ * This class is to be used when one wants to add, remove and
+ * update features in a store.
  *
+ * Consider using a {<GeoExt.data.LayerStoreMediator>} instance
+ * instead of a {<GeoExt.data.RecordLayerMediator>} as a
+ * {<GeoExt.data.LayerStoreMediator>} instance will take care
+ * of automatically synchronizing the vector layer and the
+ * store.
+ *
  * Usage example:
  * (start code)
  * var store = new Ext.data.Store({
@@ -41,6 +48,9 @@
  *         return feature.state != OpenLayers.State.UNKNOWN;
  *     }
  * });
+ * var feature = new OpenLayers.Feature.Vector(
+ *     new OpenLayers.Geometry.Point(1.0, 2.0));
+ * mediator.addFeatures([feature]);
  * (end)
  */
 
@@ -71,7 +81,7 @@
 GeoExt.data.FeatureStoreMediator.prototype = {
     /**
      * APIProperty: store
-     * {Ext.data.Store} An Ext data store
+     * {Ext.data.Store} An Ext data store.
      */
     store: null,
 
@@ -93,15 +103,18 @@
 
     /**
      * APIMethod: addFeatures
-     *      Add features to the store.
+     *     Add features to the store. Actually records created by the
+     *     {<GeoExt.data.FeatureReader>} reader configured in the
+     *     store are added to the store.
      * 
      * Parameters:
-     * features - {<OpenLayers.Feature.Vector>} or
-     *     {Array{<OpenLayers.Feature.Vector>}} A feature or an
-     *     array of features to add to the store.
-     * config - a config object which can include the properties
+     * features - {OpenLayers.Feature.Vector} or
+     *     {Array{OpenLayers.Feature.Vector}} A feature or an
+     *     array of features from which the records to add to
+     *     the store are created.
+     * config - {Object} A config object which can include the properties
      *     "append" and "filter", if set these properties will
-     *     override that set in the object.
+     *     override those set in the object.
      */
     addFeatures: function(features, config) {
         if (!Ext.isArray(features)) {
@@ -133,14 +146,57 @@
     },
 
     /**
+     * APIMethod: updateFeatures
+     *     Update the data of the records in the store based on the
+     *     passed features.
+     *
+     * Parameters:
+     * features - {OpenLayers.Feature.Vector} or
+     *     {Array{OpenLayers.Feature.Vector}} A feature or an
+     *     array of features whose corresponding records are to
+     *     be updated.
+     */
+    updateFeatures: function(features) {
+        if (!Ext.isArray(features)) {
+            features = [features];
+        }
+
+        var fields = this.store.recordType.prototype.fields;
+        var i, lenI, j, lenJ, feature, record, attributes, field, v;
+
+        for (i = 0, lenI = features.length; i < lenI; i++) {
+            feature = features[i];
+            record = this.store.getById(feature.id);
+            if (record !== undefined) {
+                record.beginEdit();
+                attributes = feature.attributes;
+                if (attributes) {
+                    for (j = 0, lenJ = fields.length; j < lenJ; j++) {
+                        field = fields.items[j];
+                        v = attributes[field.mapping || field.name] ||
+                            field.defaultValue;
+                        v = field.convert(v);
+                        record.set(field.name, v);
+                    }
+                }
+                record.set("state", feature.state);
+                record.set("fid", feature.fid);
+                record.endEdit();
+            }
+        }
+    },
+
+    /**
      * APIMethod: removeFeatures
-     *      Remove features from the store.
+     *     Remove the records corresponding to the passed features
+     *     from the store.
      *
      * Parameters:
-     * features - {<OpenLayers.Feature.Vector>} or
-     *      {Array{<OpenLayers.Feature.Vector>}} A feature or an
-     *      array of features to remove from the store. If null
-     *      all the features in the store are removed.
+     * features - {OpenLayers.Feature.Vector} or
+     *      {Array{OpenLayers.Feature.Vector}} A feature or an
+     *      array of features whose corresponding records are to
+     *      be removed from the store. If null all the records
+     *      in the store are removed.
      */
     removeFeatures: function(features) {
         if (!features) {

Modified: sandbox/elemoine/playground/lib/GeoExt/data/LayerStoreMediator.js
===================================================================
--- sandbox/elemoine/playground/lib/GeoExt/data/LayerStoreMediator.js	2009-02-19 23:00:48 UTC (rev 206)
+++ sandbox/elemoine/playground/lib/GeoExt/data/LayerStoreMediator.js	2009-02-20 23:53:05 UTC (rev 207)
@@ -18,7 +18,8 @@
  */
 
 /**
- * @requires GeoExt/data/FeatureStoreMediator.js
+ * @include GeoExt/data/FeatureStoreMediator.js
+ * @include GeoExt/data/LayerRecordMediator.js
  */
 
 Ext.namespace('GeoExt', 'GeoExt.data');
@@ -26,9 +27,15 @@
 /**
  * Class: GeoExt.data.LayerStoreMediator
  *
- * This class is to be used when one wants to insert, remove, and
- * update features in a grid as a result of features being inserted,
- * removed, modified in a vector layer.
+ * This class can be used for synchronizing a vector layer and a
+ * feature store. When records are added to the store the
+ * corresponding features are added to the layer, when records
+ * are removed from the store the corresponding features are
+ * removed from the layer, when the data of records are changed
+ * the attributes of the corresponding features are updated.
+ * The synchronization also works in the other direction, for
+ * example when features are added to a layer corresponding
+ * records are added to the store.
  *
  * Usage example:
  * (start code)
@@ -39,6 +46,7 @@
  *     )
  * });
  * var mediator = new GeoExt.data.LayerStoreMediator({
+ *     layer: layer,
  *     store: store,
  *     filter: function(feature) {
  *         return feature.state != OpenLayers.State.UNKNOWN;
@@ -61,17 +69,15 @@
  * {<GeoExt.data.LayerStoreMediator>}
  */
 GeoExt.data.LayerStoreMediator = function(config) {
-    var store = config.store;
-    // no need to place the store in the instance
-    delete config.store;
+    this.direction = GeoExt.data.LayerStoreMediator.LAYER_TO_STORE |
+                     GeoExt.data.LayerStoreMediator.STORE_TO_LAYER;
     Ext.apply(this, config);
-    if (!this.layer) {
-        OpenLayers.Console.error(
-            "layer is missing in config");
-    }
     this.featureStoreMediator = new GeoExt.data.FeatureStoreMediator({
-        store: store
+        store: this.store
     });
+    this.recordLayerMediator = new GeoExt.data.RecordLayerMediator({
+        layer: this.layer
+    });
     if (this.autoActivate) {
         this.activate();
     }
@@ -85,6 +91,30 @@
     layer: null,
 
     /**
+     * APIProperty: store
+     * {Ext.data.Store} A store configured with a {<GeoExt.data.FeatureReader>}
+     * instance.
+     */
+    store: null,
+
+    /**
+     * APIProperty: direction
+     * {Number} Bitfields specifying the synchronization direction, if set to
+     * GeoExt.data.LayerStoreMediator.LAYER_TO_STORE the synchronization is
+     * done in the layer-to-store direction, if set to
+     * GeoExt.data.LayerStoreMediator.STORE_TO_LAYER the synchronization
+     * is done in the store-to-layer direction ; by default the synchronization
+     * is done in both directions :
+     * (code)
+     * mediator.direction = GeoExt.data.LayerStoreMediator.LAYER_TO_STORE |
+     *                      GeoExt.data.LayerStoreMediator.STORE_TO_LAYER;
+     * (end)
+     * The value of this property can be changed after the mediator
+     * instance has been created.
+     */
+    direction: null,
+
+    /**
      * APIProperty: filter
      * {Function} a filter function called for each feature to be
      * inserted, the feature is passed as an argument to the function,
@@ -111,12 +141,20 @@
     /**
      * Property: featureStoreMediator
      * {<GeoExt.data.featureStoreMediator>} An internal
-     * feature store mediator for manually adding features to the
-     * Ext store.
+     * feature store mediator for adding/removing/updating
+     * records to/from/in the store.
      */
     featureStoreMediator: null,
 
     /**
+     * Property: recordLayerMediator
+     * {<GeoExt.data.recordLayerMediator>} An internal
+     * record layer mediator for adding/removing/updating
+     * features to/from/in the layer.
+     */
+    recordStoreMediator: null,
+
+    /**
      * APIMethod: activate
      * Activate the mediator.
      *
@@ -126,12 +164,8 @@
      */
     activate: function() {
         if (!this.active) {
-            this.layer.events.on({
-                featuresadded: this.update,
-                featuresremoved: this.update,
-                featuremodified: this.update,
-                scope: this
-            });
+            this.layerEventsOn();
+            this.storeEventsOn();
             this.active = true;
             return true;
         }
@@ -148,28 +182,172 @@
      */
     deactivate: function() {
         if (this.active) {
-            this.layer.events.un({
-                featuresadded: this.update,
-                featuresremoved: this.update,
-                featuremodified: this.update,
-                scope: this
-            });
+            this.layerEventsOff();
+            this.storeEventsOff();
             return true;
         }
         return false;
     },
 
     /**
-     * Method: update
-     *      Called when features are added, removed or modified. This
-     *      function empties the store, loops over the features in
-     *      the layer, and for each feature calls the user-defined
-     *      filter function, if the return value of the filter function
-     *      evaluates to true the feature is added to the store.
+     * Method: layerEventsOn
+     * Register the layer event listeners.
      */
-    update: function() {
-        this.featureStoreMediator.addFeatures(
-            this.layer.features,
-            {append: false, filter: this.filter});
+    layerEventsOn: function() {
+        this.layer.events.on({
+            featuresadded: this.onFeaturesadded,
+            featuresremoved: this.onFeaturesremoved,
+            featuremodified: this.onFeaturemodified,
+            scope: this
+        });
+    },
+
+    /**
+     * Method: layerEventsOff
+     * Unregister the layer event listeners.
+     */
+    layerEventsOff: function() {
+        this.layer.events.un({
+            featuresadded: this.onFeaturesadded,
+            featuresremoved: this.onFeaturesremoved,
+            featuremodified: this.onFeaturemodified,
+            scope: this
+        });
+    },
+
+    /**
+     * Method: storeEventsOn
+     * Register the store event listeners.
+     */
+    storeEventsOn: function() {
+        this.store.on("load", this.onLoad, this);
+        this.store.on("add", this.onAdd, this);
+        this.store.on("remove", this.onRemove, this);
+        this.store.on("update", this.onUpdate, this);
+    },
+
+    /**
+     * Method: storeEventsOff
+     * Unregister the store event listeners.
+     */
+    storeEventsOff: function() {
+        this.store.un("load", this.onLoad, this);
+        this.store.un("add", this.onAdd, this);
+        this.store.un("remove", this.onRemove, this);
+        this.store.un("update", this.onUpdate, this);
+    },
+
+    /**
+     * Method: onFeaturesadded
+     * Called when features are added to the layer, adds the features
+     * to the store.
+     *
+     * Parameters:
+     * obj - {Object} An object with a "features" property referencing
+     * the features added to the layer.
+     */
+    onFeaturesadded: function(obj) {
+        if (this.direction & GeoExt.data.LayerStoreMediator.LAYER_TO_STORE) {
+            this.storeEventsOff();
+            this.featureStoreMediator.addFeatures(obj.features,
+                {append: true, filter: this.filter});
+            this.storeEventsOn();
+        }
+    },
+
+    /**
+     * Method: onFeaturesremoved
+     * Called when features are removed from the layer, removes the
+     * features from the store.
+     *
+     * Parameters:
+     * obj - {Object} An object with a "features" property referencing
+     * the features added to the layer.
+     */
+    onFeaturesremoved: function(obj) {
+        if (this.direction & GeoExt.data.LayerStoreMediator.LAYER_TO_STORE) {
+            this.storeEventsOff();
+            this.featureStoreMediator.removeFeatures(obj.features);
+            this.storeEventsOn();
+        }
+    },
+
+    /**
+     * Method: onFeaturemodified
+     * Called when a feature is modified in the layer, updates the
+     * corresponding store records.
+     *
+     * Parameters:
+     * obj - {Object} An object with a "feature" property referencing
+     * the modified feature.
+     */
+    onFeaturemodified: function(obj) {
+        if (this.direction & GeoExt.data.LayerStoreMediator.LAYER_TO_STORE) {
+            this.storeEventsOff();
+            this.featureStoreMediator.updateFeatures(obj.feature);
+            this.storeEventsOn();
+        }
+    },
+    /**
+     * Method: onLoad
+     * Called when records are loaded into the store.
+     */
+    onLoad: function(store, records, options) {
+        // if options.add is true we let onAdd do the work
+        if ((this.direction & GeoExt.data.LayerStoreMediator.STORE_TO_LAYER) &&
+            !options || options.add !== true) {
+            this.layerEventsOff();
+            this.recordLayerMediator.addRecords(records, {append: false});
+            this.layerEventsOn();
+        }
+    },
+
+    /**
+     * Method: onAdd
+     * Called when records are added to the store.
+     */
+    onAdd: function(store, records, index) {
+        if (this.direction & GeoExt.data.LayerStoreMediator.STORE_TO_LAYER) {
+            this.layerEventsOff();
+            this.recordLayerMediator.addRecords(records);
+            this.layerEventsOn();
+        }
+    },
+
+    /**
+     * Method: onRemove
+     * Called when a record is removed from the store.
+     */
+    onRemove: function(store, record, index) {
+        if (this.direction & GeoExt.data.LayerStoreMediator.STORE_TO_LAYER) {
+            this.layerEventsOff();
+            this.recordLayerMediator.removeRecords(record);
+            this.layerEventsOn();
+        }
+    },
+
+    /**
+     * Method: onUpdate
+     * Called when a record is updated.
+     */
+    onUpdate: function(store, record, operation) {
+        if ((this.direction & GeoExt.data.LayerStoreMediator.STORE_TO_LAYER) &&
+            operation == Ext.data.Record.EDIT) {
+            this.layerEventsOff();
+            this.recordLayerMediator.updateRecords(record);
+            this.layerEventsOn();
+        }
     }
 };
+
+/**
+ * Constant: GeoExt.data.LayerStoreMediator.LAYER_TO_STORE
+ */
+GeoExt.data.LayerStoreMediator.LAYER_TO_STORE = 1;
+
+/**
+ * Constant: GeoExt.data.LayerStoreMediator.STORE_TO_LAYER
+ */
+GeoExt.data.LayerStoreMediator.STORE_TO_LAYER = 2;
+
+

Added: sandbox/elemoine/playground/lib/GeoExt/data/RecordLayerMediator.js
===================================================================
--- sandbox/elemoine/playground/lib/GeoExt/data/RecordLayerMediator.js	                        (rev 0)
+++ sandbox/elemoine/playground/lib/GeoExt/data/RecordLayerMediator.js	2009-02-20 23:53:05 UTC (rev 207)
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2008 Eric Lemoine, Camptocamp France SAS
+ *
+ * This file is part of GeoExt
+ *
+ * GeoExt is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GeoExt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GeoExt.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @include GeoExt/data/FeatureReader.js
+ */
+
+Ext.namespace('GeoExt', 'GeoExt.data');
+
+/**
+ * Class: GeoExt.data.RecordLayerMediator
+ * This class can be used to, from {Ext.data.Record} objects created
+ * with a {<GeoExt.data.FeatureReader>}, add features to a layer,
+ * remove features from a layer, and update features in a layer.
+ *
+ * Consider using a {<GeoExt.data.LayerStoreMediator>} instance
+ * instead of a {<GeoExt.data.RecordLayerMediator>} as a
+ * {<GeoExt.data.LayerStoreMediator>} instance will take care
+ * of automatically synchronizing the vector layer and the
+ * store.
+ *
+ * Usage example:
+ * (start code)
+ * // create a feature store
+ * var store = new Ext.data.Store({
+ *     reader: new GeoExt.data.FeatureReader(
+ *         {}, [{name: "name", type: "string"}]
+ *     )
+ * });
+ * // create a vector layer
+ * var layer = new OpenLayers.Layer.Vector('vector');
+ * // with the code below when records are loaded into the store,
+ * // the features corresponding to the loaded records are
+ * // automatically added to the layer.
+ * var mediator = new GeoExt.data.RecordLayerMediator({
+ *     layer: layer
+ * });
+ * store.on("load", function(store, records, options) {
+ *     mediator.addRecords(records, {append: options.add});
+ * });
+ * (end)
+ */
+
+/**
+ * Constructor: GeoExt.data.RecordLayerMediator
+ * Create an instance of GeoExt.data.RecordLayerMediator
+ *
+ * Parameters:
+ * config - {Object} A config object used to set the record
+ *     layer mediator's properties, see below for the list
+ *     of supported properties.
+ *
+ * Returns:
+ * {<GeoExt.data.RecordLayerMediator>}
+ */
+GeoExt.data.RecordLayerMediator = function(config) {
+    Ext.apply(this, config);
+    if (!this.layer) {
+        OpenLayers.Console.error(
+            "layer is missing in the config");
+    }
+};
+
+GeoExt.data.RecordLayerMediator.prototype = {
+    /**
+     * Property: layer
+     * {OpenLayers.Layer.Vector} A vector layer.
+     */
+    layer: null,
+
+    /**
+     * Property: append
+     * {Boolean} False if the layer must be cleared before adding new
+     * features into it, false otherwise; defaults to true.
+     */
+    append: true,
+
+    /**
+     * Property: filter
+     * {Function} a filter function called for each record in the
+     * records array, the record is passed as an argument to the
+     * function, it it returns true the feature corresponding
+     * to the record in added to the layer, otherwise it's not.
+     */
+    filter: null,
+
+    /**
+     * Method: addRecords
+     *     Add the features corresponding to passed records to the
+     *     layer.
+     *
+     * Parameters:
+     * records - {Ext.data.Record} or {Array{Ext.data.Record}} A
+     *     record or an array of records whose corresponding features
+     *     are to be added to the layer.
+     * config - {Object} A config object which can include the properties
+     *     "append" and "filter", if set these properties will override
+     *     those set in the object.
+     */
+    addRecords: function(records, config) {
+        if (!Ext.isArray(records)) {
+            records = [records];
+        }
+        config = OpenLayers.Util.applyDefaults(config,
+            {append: this.append, filter: this.filter});
+        var toAdd = records;
+        if (config.filter) {
+            toAdd = [];
+            var record;
+            for (var i = 0, len = records.length; i < len; i++) {
+                record = records[i];
+                if (config.filter(record)) {
+                    toAdd.push(record);
+                }
+            }
+        }
+        if (config && !config.append) {
+            this.layer.removeFeatures(this.layer.features);
+        }
+        if (toAdd) {
+            var len = toAdd.length;
+            if (len > 0) {
+                var features = new Array(len);
+                for (var i = 0; i < len; i++) {
+                    features[i] = toAdd[i].get("feature");
+                }
+                this.layer.addFeatures(features);
+            }
+        }
+    },
+
+    /**
+     * Method: updateRecords
+     *     Update the features in the layer based on the data
+     *     of the passed records.
+     *
+     * Parameters:
+     * records - {Ext.data.Record} or
+     *     {Array{Ext.data.Record}} A record or an array of records
+     *     whose corresponding features are updated (their attributes)
+     *     and redrawn.
+     */
+    updateRecords: function(records) {
+        if (records) {
+            if (!Ext.isArray(records)) {
+                records = [records];
+            }
+            var i, lenI = records.length, record, feature;
+            var j, lenJ;
+            for (i = 0; i < lenI; i++) {
+                record = records[i];
+                feature = this.layer.getFeatureById(record.id);
+                if (feature) {
+                    if (record.fields) {
+                        record.fields.each(function(field) {
+                            feature.attributes[field.mapping || field.name] =
+                                record.get(field.name);
+                        });
+                    }
+                    this.layer.drawFeature(feature);
+                }
+            }
+        }
+    },
+
+    /**
+     * Method: removeRecords
+     *     Remove the features corresponding to the passed records
+     *     from the layer.
+     *
+     * Parameters:
+     * records - {Ext.data.Record} or {Array{Ext.data.Record}} A 
+     *     record or an array of reccords whose corresponding
+     *     features are to be removed from the layer. If null
+     *     all the features are removed from the layer.
+     */
+    removeRecords: function(records) {
+        var toRemove;
+        if (!records) {
+            if (this.layer.features.length > 0) {
+                toRemove = this.layer.features;
+            }
+        } else {
+            if (!Ext.isArray(records)) {
+                records = [records];
+            }
+            var len = records.length;
+            if (len > 0) {
+                var features = new Array(len);
+                for (var i = 0; i < len; i++) {
+                    features[i] = records[i].get("feature");
+                }
+                toRemove = features;
+            }
+        }
+        if (toRemove !== undefined) {
+            this.layer.removeFeatures(toRemove);
+        }
+    }
+};

Modified: sandbox/elemoine/playground/lib/GeoExt.js
===================================================================
--- sandbox/elemoine/playground/lib/GeoExt.js	2009-02-19 23:00:48 UTC (rev 206)
+++ sandbox/elemoine/playground/lib/GeoExt.js	2009-02-20 23:53:05 UTC (rev 207)
@@ -76,6 +76,7 @@
             "GeoExt/data/FeatureReader.js",
             "GeoExt/data/FeatureStore.js",
             "GeoExt/data/FeatureStoreMediator.js",
+            "GeoExt/data/RecordLayerMediator.js",
             "GeoExt/data/LayerStoreMediator.js",
             "GeoExt/data/ProtocolProxy.js"
         );

Modified: sandbox/elemoine/playground/tests/data/LayerStoreMediator.html
===================================================================
--- sandbox/elemoine/playground/tests/data/LayerStoreMediator.html	2009-02-19 23:00:48 UTC (rev 206)
+++ sandbox/elemoine/playground/tests/data/LayerStoreMediator.html	2009-02-20 23:53:05 UTC (rev 207)
@@ -9,7 +9,7 @@
 
     <script type="text/javascript">
         function test_constructor(t) {
-            t.plan(3);
+            t.plan(5);
             // setup
             var mediator, store, layer;
             store = new Ext.data.Store({
@@ -31,6 +31,13 @@
             t.ok(mediator.featureStoreMediator instanceof
                      GeoExt.data.FeatureStoreMediator,
                  "ctor correctly creates feature store mediator");
+            t.ok(mediator.recordLayerMediator instanceof
+                     GeoExt.data.RecordLayerMediator,
+                 "ctor correctly creates record layer mediator");
+            t.eq(mediator.direction,
+                 GeoExt.data.LayerStoreMediator.LAYER_TO_STORE |
+                 GeoExt.data.LayerStoreMediator.STORE_TO_LAYER,
+                 "ctor correctly the default sync direction");
         }
         function test_events(t) {
             t.plan(3);
@@ -45,24 +52,33 @@
             mediator = new GeoExt.data.LayerStoreMediator({
                 store: store,
                 layer: layer,
-                update: function() {
-                    t.ok(true, "update called on " + eventType);
+                onFeaturesadded: function(obj) {
+                    t.ok(obj.features !== undefined,
+                         "onFeaturesadded called on " + eventType);
+                },
+                onFeaturesremoved: function(obj) {
+                    t.ok(obj.features !== undefined,
+                         "onFeaturesremoved called on " + eventType);
+                },
+                onFeaturemodified: function(obj) {
+                    t.ok(obj.feature !== undefined,
+                         "onFeaturesremoved called on " + eventType);
                 }
             });
             // 1 test
             eventType = "featuresadded";
-            layer.events.triggerEvent(eventType);
+            layer.events.triggerEvent(eventType, {features: null});
             // 1 test
             eventType = "featuresremoved";
-            layer.events.triggerEvent(eventType);
+            layer.events.triggerEvent(eventType, {features: null});
             // 1 test
             eventType = "featuremodified";
-            layer.events.triggerEvent(eventType);
+            layer.events.triggerEvent(eventType, {feature: null});
         }
-        function test_update(t) {
-            t.plan(2);
+        function test_layer_events(t) {
+            t.plan(3);
             // setup
-            var mediator, store, layer;
+            var mediator, store, layer, features;
             store = new Ext.data.Store({
                 reader: new GeoExt.data.FeatureReader(
                     {}, [{name: "name", type: "string"}]
@@ -80,16 +96,87 @@
                 ];
             }
             // 1 test
-            layer.features = createFeatures();
-            layer.events.triggerEvent("featuresadded");
+            features = createFeatures();
+            layer.events.triggerEvent("featuresadded",
+                                      {features: features});
             t.eq(store.getCount(), 2,
-                 "featuresadded event caused insertion of 2 records"); 
+                 "featuresadded event causes insertion of records"); 
             // 1 test
-            layer.features = createFeatures();
-            layer.events.triggerEvent("featuresadded");
-            t.eq(store.getCount(), 2,
-                 "featuresadded event caused insertion of 2 records"); 
+            features[0].attributes.name = "foofoo";
+            layer.events.triggerEvent("featuremodified",
+                                      {feature: features[0]});
+            t.eq(store.getById(features[0].id).get("name"), "foofoo",
+                 "featuremodified event causes update of correct record");
+            // 1 test
+            layer.events.triggerEvent("featuresremoved",
+                                      {features: features});
+            t.eq(store.getCount(), 0,
+                 "featuresremoved event causes removal of records"); 
         }
+        function test_store_events(t) {
+            t.plan(6);
+            // setup
+            var mediator, store, layer, records;
+            store = new Ext.data.Store({
+                reader: new GeoExt.data.FeatureReader(
+                    {}, [{name: "name", type: "string"}]
+                )
+            });
+            layer = new OpenLayers.Layer.Vector();
+            mediator = new GeoExt.data.LayerStoreMediator({
+                store: store,
+                layer: layer
+            });
+            function createFeatures() {
+                return [
+                    new OpenLayers.Feature.Vector(null, {name: "foo"}),
+                    new OpenLayers.Feature.Vector(null, {name: "bar"})
+                ];
+            }
+            function createRecords() {
+                var f1 = new OpenLayers.Feature.Vector(
+                    null, {name: "foo"});
+                var f2 = new OpenLayers.Feature.Vector(
+                    null, {name: "bar"});
+                return [
+                    new store.recordType({
+                        feature: f1,
+                        name: "foo",
+                        fid: 1
+                    }, f1.id),
+                    new store.recordType({
+                        feature: f2,
+                        name: "bar",
+                        fid: 2
+                    }, f2.id)
+                ];
+            }
+            // 1 test
+            store.loadData(createFeatures());
+            t.eq(layer.features.length, 2,
+                 "store.loadData causes loading of features in layer");
+            // 1 test
+            store.loadData(createFeatures());
+            t.eq(layer.features.length, 2,
+                 "store.loadData causes loading of new features in layer");
+            // 1 test
+            store.loadData(createFeatures(), true);
+            t.eq(layer.features.length, 4,
+                 "store.loadData causes addition of features in layer");
+            // 1 test
+            records = createRecords();
+            store.add(records);
+            t.eq(layer.features.length, 6,
+                 "store.add causes addition of features in layer");
+            // 1 test
+            store.remove(records[0]);
+            t.eq(layer.features.length, 5,
+                 "store.remove causes removal of a feature in layer");
+            // 1 test
+            records[1].set("name", "foofoo");
+            t.eq(layer.getFeatureById(records[1].id).attributes.name, "foofoo",
+                 "record.set causes update of corresponding feature");
+        }
     </script>
   <body>
     <div id="map"></div>



More information about the Commits mailing list