Ticket #38: patch-38-r369-A0.diff

File patch-38-r369-A0.diff, 11.6 kB (added by elemoine, 1 year ago)
  • tests/lib/GeoExt/data/LayerStore.html

    old new  
    7373            t.eq(map.layers.length,1,"Adding layer to MapPanel's LayerStore adds only one layer to map"); 
    7474            t.eq(mapPanel.layers.getCount(),1,"Adding layers to MapPanel's LayerStore does not create duplicate layers");  
    7575        } 
     76 
     77        function test_load_clear(t) { 
     78            t.plan(2); 
     79             
     80            var map = new OpenLayers.Map("mappanel"); 
     81            var store = new GeoExt.data.LayerStore({ 
     82                map: map 
     83            }); 
     84 
     85            store.loadData([ 
     86                new OpenLayers.Layer.Vector(), 
     87                new OpenLayers.Layer.Vector() 
     88            ]); 
     89            t.eq(map.layers.length, 2, "loading the store with two records adds two layers to the map"); 
     90 
     91            store.removeAll(); 
     92            t.eq(map.layers.length, 0, "clearing the store removes all layers from map"); 
     93        } 
    7694         
     95        function test_bind_unbind(t) { 
     96            t.plan(22); 
     97             
     98            var map = new OpenLayers.Map("mappanel"); 
     99            var store = new GeoExt.data.LayerStore(); 
     100            var layers = [new OpenLayers.Layer.Vector("Foo layer"), 
     101                          new OpenLayers.Layer.Vector("Bar layer")]; 
     102            var records = [ 
     103                new GeoExt.data.LayerRecord({ 
     104                    layer: new OpenLayers.Layer.Vector("Foo record")}), 
     105                new GeoExt.data.LayerRecord({ 
     106                    layer: new OpenLayers.Layer.Vector("Bar record")}) 
     107            ]; 
     108 
     109            var reinit_test_data = function () { 
     110                // unbind store 
     111                store.unbind(); 
     112 
     113                // remove all existing records and layers 
     114                store.removeAll(); 
     115                for (var i=map.layers.length - 1; i>=0; i--) { 
     116                    map.removeLayer(map.layers[i]); 
     117                } 
     118                t.eq(map.layers.length, 0, "there is no more layers in the map"); 
     119                t.eq(store.getCount(), 0, "there is no more records in the store"); 
     120 
     121                // add testing data to store and map 
     122                store.add(records); 
     123                map.addLayers(layers); 
     124                t.eq(map.layers.length, 2, "initial layers are loaded in the map"); 
     125                t.eq(store.getCount(), 2, "initial records are loaded in the store"); 
     126            }; 
     127             
     128            // test store to map synchronization 
     129            reinit_test_data(); 
     130            store.bind(map, {initDir: GeoExt.data.LayerStore.STORE_TO_MAP}); 
     131            t.eq(map.layers.length, 4, "initial records are synchronized to map"); 
     132            t.eq(store.getCount(), 2, "initial layers are not synchronized to store"); 
     133            map.removeLayer(layers[0]); 
     134            t.eq(map.layers.length, 3, "removing layer not present in store has been well removed"); 
     135            t.eq(store.getCount(), 2, "nothing to remove in store when removing layer not present in store"); 
     136 
     137            // test map to store synchronization 
     138            reinit_test_data(); 
     139            store.bind(map, {initDir: GeoExt.data.LayerStore.MAP_TO_STORE}); 
     140            t.eq(map.layers.length, 2, "initial records are not synchronized to map"); 
     141            t.eq(store.getCount(), 4, "initial layers are synchronized to store"); 
     142            store.remove(records[0]); 
     143            t.eq(store.getCount(), 3, "removing record not present in map has been well removed"); 
     144            t.eq(map.layers.length, 2, "nothing to remove in map when removing record not present in map"); 
     145 
     146 
     147            // test both synchronization 
     148            reinit_test_data(); 
     149            store.bind(map); 
     150            t.eq(map.layers.length, 4, "initial records are synchronized to map"); 
     151            t.eq(store.getCount(), 4, "initial layers are synchronized to store"); 
     152        } 
     153 
    77154        function test_add_remove(t) { 
    78155             
    79156            t.plan(2); 
  • lib/GeoExt/data/LayerStore.js

    old new  
    6464     * recordType - {<GeoExt.data.LayerRecord>} If provided, a custom layer 
    6565     *     record type with additional fields will be used. Default fields for 
    6666     *     every layer record are {OpenLayers.Layer} layer and {String} title. 
     67     * initDir - {Number} Bitfields specifying the direction to use for the 
     68     *     initial sync between the map and the store, if set to 0 then no 
     69     *     initial sync is done. Defaults to 
     70     *     <GeoExt.data.LayerStore.MAP_TO_STORE>|<GeoExt.data.LayerStore.STORE_TO_MAP>. 
    6771     */ 
    6872    constructor: function(config) { 
    6973        config = config || {}; 
    7074        config.reader = config.reader || 
    7175                        new GeoExt.data.LayerReader({}, config.recordType); 
     76        // "map" option 
    7277        var map = config.map instanceof GeoExt.MapPanel ? 
    7378                  config.map.map : config.map; 
    7479        delete config.map; 
     80        // "layers" option - is an alias to "data" option 
     81        if(config.layers) { 
     82            config.data = config.layers; 
     83        } 
     84        delete config.layers; 
     85        // "initDir" option 
     86        var options = {initDir: config.initDir}; 
     87        delete config.initDir; 
    7588        arguments.callee.superclass.constructor.call(this, config); 
    7689        if(map) { 
    77             // create a snapshop of the map's layers 
    78             var layers = map.layers; 
    79             var layer; 
    80             // walk through the layers snapshot and add layers to the store 
    81             for(var i=0; i<layers.length; ++i) { 
    82                 layer = layers[i]; 
    83                 this.add((this.reader.readRecords([layer])).records); 
    84             } 
    85  
    86             this.bind(map); 
    87             config.layers && map.addLayers(config.layers); 
     90            this.bind(map, options); 
    8891        } 
    8992    }, 
    9093 
     
    9598     *  
    9699     * Parameters: 
    97100     * map - {OpenLayers.Map} The map instance. 
     101     * options - {Object} 
     102     * 
     103     * Valid config options: 
     104     * initDir - {Number} Bitfields specifying the direction to use for the 
     105     *     initial sync between the map and the store, if set to 0 then no 
     106     *     initial sync is done. Defaults to 
     107     *     <GeoExt.data.LayerStore.MAP_TO_STORE>|<GeoExt.data.LayerStore.STORE_TO_MAP>. 
    98108     */ 
    99     bind: function(map) { 
    100         if(!this.map) { 
    101             this.map = map; 
    102             map.events.on({ 
    103                 "changelayer": this.onChangeLayer, 
    104                 "addlayer": this.onAddLayer, 
    105                 "removelayer": this.onRemoveLayer, 
    106                 scope: this 
    107             }); 
    108             this.on({ 
    109                 "add": this.onAdd, 
    110                 "remove": this.onRemove, 
    111                 scope: this 
    112             }); 
     109    bind: function(map, options) { 
     110        if(this.map) { 
     111            // already bound 
     112            return; 
    113113        } 
     114        this.map = map; 
     115        options = options || {}; 
     116 
     117        var initDir = options.initDir; 
     118        if(options.initDir == undefined) { 
     119            initDir = GeoExt.data.LayerStore.MAP_TO_STORE | 
     120                      GeoExt.data.LayerStore.STORE_TO_MAP; 
     121        } 
     122 
     123        // create a snapshot of the map's layers 
     124        var layers = map.layers.slice(0); 
     125 
     126        if(initDir & GeoExt.data.LayerStore.STORE_TO_MAP) { 
     127            var records = this.getRange(); 
     128            for(var i=records.length - 1; i>=0; i--) { 
     129                this.map.addLayer(records[i].get("layer")); 
     130            } 
     131        } 
     132        if(initDir & GeoExt.data.LayerStore.MAP_TO_STORE) { 
     133            this.loadData(layers, true); 
     134        } 
     135 
     136        map.events.on({ 
     137            "changelayer": this.onChangeLayer, 
     138            "addlayer": this.onAddLayer, 
     139            "removelayer": this.onRemoveLayer, 
     140            scope: this 
     141        }); 
     142        this.on({ 
     143            "load": this.onLoad, 
     144            "clear": this.onClear, 
     145            "add": this.onAdd, 
     146            "remove": this.onRemove, 
     147            scope: this 
     148        }); 
    114149    }, 
    115150 
    116151    /** 
     
    125160                "removelayer": this.onRemoveLayer, 
    126161                scope: this 
    127162            }); 
    128             this.un({ 
    129                 "add": this.onAdd, 
    130                 "remove": this.onRemove, 
    131                 scope: this 
    132             }); 
     163            this.un("load", this.onLoad, this); 
     164            this.un("clear", this.onClear, this); 
     165            this.un("add", this.onAdd, this); 
     166            this.un("remove", this.onRemove, this); 
     167 
    133168            this.map = null; 
    134169        } 
    135170    }, 
     
    176211        if(!this._adding) { 
    177212            var layer = evt.layer; 
    178213            this._adding = true; 
    179             this.add((this.reader.readRecords([layer])).records); 
     214            this.loadData([layer], true); 
    180215            delete this._adding; 
    181216        } 
    182217    }, 
     
    198233    }, 
    199234     
    200235    /** 
     236     * Method: onLoad 
     237     * Handler for a store's load event 
     238     *  
     239     * Parameters: 
     240     * store - {<Ext.data.Store>} 
     241     * records - {Array(Ext.data.Record)} 
     242     * options - {Object} 
     243     */ 
     244    onLoad: function(store, records, options) { 
     245        if (!Ext.isArray(records)) { 
     246            records = [records]; 
     247        } 
     248        if (options && !options.add) { 
     249            this._removing = true; 
     250            for (var i = this.map.layers.length - 1; i >= 0; i--) { 
     251                this.map.removeLayer(this.map.layers[i]); 
     252            } 
     253            delete this._removing; 
     254 
     255            // layers has already been added to map on "add" event 
     256            var len = records.length; 
     257            if (len > 0) { 
     258                var layers = new Array(len); 
     259                for (var j = 0; j < len; j++) { 
     260                    layers[j] = records[j].get("layer"); 
     261                } 
     262                this._adding = true; 
     263                this.map.addLayers(layers); 
     264                delete this._adding; 
     265            } 
     266        } 
     267    }, 
     268     
     269    /** 
     270     * Method: onClear 
     271     * Handler for a store's clear event 
     272     *  
     273     * Parameters: 
     274     * store - {<Ext.data.Store>} 
     275     */ 
     276    onClear: function(store) { 
     277        this._removing = true; 
     278        for (var i = this.map.layers.length - 1; i >= 0; i--) { 
     279            this.map.removeLayer(this.map.layers[i]); 
     280        } 
     281        delete this._removing; 
     282    }, 
     283     
     284    /** 
    201285     * Method: onAdd 
    202286     * Handler for a store's add event 
    203287     *  
     
    232316     */ 
    233317    onRemove: function(store, record, index){ 
    234318        if(!this._removing) { 
    235             this._removing = true; 
    236             this.map.removeLayer(record.get("layer")); 
    237             delete this._removing; 
     319            var layer = record.get("layer"); 
     320            if (this.map.getLayer(layer.id) != null) { 
     321                this._removing = true; 
     322                this.map.removeLayer(record.get("layer")); 
     323                delete this._removing; 
     324            } 
    238325        } 
    239326    } 
    240327}; 
     
    260347    Ext.data.Store, 
    261348    GeoExt.data.LayerStoreMixin 
    262349); 
     350 
     351/** 
     352 * Constant: GeoExt.data.LayerStore.MAP_TO_STORE 
     353 * {Integer} Constant used to make the store be automatically updated 
     354 * when changes occur in the map. 
     355 */ 
     356GeoExt.data.LayerStore.MAP_TO_STORE = 1; 
     357 
     358/** 
     359 * Constant: GeoExt.data.LayerStore.STORE_TO_MAP 
     360 * {Integer} Constant used to make the map be automatically updated 
     361 * when changes occur in the store. 
     362 */ 
     363GeoExt.data.LayerStore.STORE_TO_MAP = 2;