Skip to content

Commit

Permalink
Synchronize in both directions. Read values on load.
Browse files Browse the repository at this point in the history
  • Loading branch information
simonseyock committed May 21, 2021
1 parent e620e41 commit 075a85c
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 40 deletions.
8 changes: 5 additions & 3 deletions src/data/model/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ Ext.define('GeoExt.data.model.Layer', {
unnamedGroupLayerText: 'Unnamed Group Layer',

/**
* This property specifies which properties are synchronized from the
* record to the ol layer object.
* This property specifies which properties are synchronized between
* the store record and the ol layer object.
*
* By default this only the property `'title'`.
*
* @cfg {string[]}
*/
synchronizePropertiesToMap: ['title'],
synchronizedProperties: ['title'],

fields: [
{
Expand Down
101 changes: 73 additions & 28 deletions src/data/store/Layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Ext.define('GeoExt.data.store.Layers', {
});

mapLayers.forEach(function(layer) {
layer.on('propertychange', me.onChangeLayer, me);
me.bindLayer(layer);
});
mapLayers.on('add', me.onAddLayer, me);
mapLayers.on('remove', me.onRemoveLayer, me);
Expand Down Expand Up @@ -156,6 +156,47 @@ Ext.define('GeoExt.data.store.Layers', {
}
},

/**
* Bind the layer to the record and initialize synchronized values.
*
* @param {ol.layer.Base} layer The layer.
* @param {Ext.data.Model} [record] The record, if not set it will be
* searched for.
*/
bindLayer: function(layer, record) {
var me = this;
layer.on('propertychange', me.onChangeLayer, me);
if (record === undefined) {
record = this.getRecordForLayer(layer);
}
Ext.Array.forEach(record.synchronizedProperties,
function(prop) {
me.synchronize(record, layer, prop);
});
},

/**
* Gets the associated record for the layer. Uses `changeLayerFilterFn` if
* set.
* @param {ol.layer.Base} layer The layer.
* @return {Ext.data.Model|undefined} The record or undefined if it doesn't
* exist.
*/
getRecordForLayer: function(layer) {
var me = this;
var recordIndex;
if (Ext.isFunction(me.changeLayerFilterFn)) {
recordIndex = this.findBy(me.changeLayerFilterFn);
} else {
recordIndex = this.findBy(function (rec) {
return rec.getOlLayer() === layer;
});
}
if (recordIndex > -1) {
return this.getAt(recordIndex);
}
},

/**
* Unbind this store from the layer collection it is currently bound.
*/
Expand Down Expand Up @@ -194,22 +235,17 @@ Ext.define('GeoExt.data.store.Layers', {
* @private
*/
onChangeLayer: function(evt) {
var me = this;
var layer = evt.target;
var recordIndex = -1;
if (Ext.isFunction(me.changeLayerFilterFn)) {
recordIndex = this.findBy(me.changeLayerFilterFn.bind(layer));
} else {
recordIndex = this.findBy(function(rec) {
return rec.getOlLayer() === layer;
});
}
if (recordIndex > -1) {
var record = this.getAt(recordIndex);
if (evt.key === 'title') {
record.set('title', layer.get('title'));
} else if (evt.key === 'description') {
var record = this.getRecordForLayer(layer);

if (record !== undefined) {
if (evt.key === 'description') {
record.set('qtip', layer.get('description'));
if (record.synchronizedProperties.indexOf('description') > -1) {
this.synchronize(record, layer, 'description');
}
} else if (record.synchronizedProperties.indexOf(evt.key) > -1) {
this.synchronize(record, layer, evt.key);
} else {
this.fireEvent('update', this, record, Ext.data.Record.EDIT,
null, {});
Expand All @@ -227,13 +263,13 @@ Ext.define('GeoExt.data.store.Layers', {
var layer = evt.element;
var index = this.layers.getArray().indexOf(layer);
var me = this;
layer.on('propertychange', me.onChangeLayer, me);
if (!me._adding) {
me._adding = true;
var result = me.proxy.reader.read(layer);
me.insert(index, result.records);
delete me._adding;
}
me.bindLayer(layer);
},

/**
Expand Down Expand Up @@ -282,8 +318,9 @@ Ext.define('GeoExt.data.store.Layers', {
if (len > 0) {
var layers = new Array(len);
for (var i = 0; i < len; i++) {
layers[i] = records[i].getOlLayer();
layers[i].on('propertychange', me.onChangeLayer, me);
var record = records[i];
layers[i] = record.getOlLayer();
me.bindLayer(layers[i], record);
}
me._adding = true;
me.layers.extend(layers);
Expand Down Expand Up @@ -325,7 +362,7 @@ Ext.define('GeoExt.data.store.Layers', {
var layer;
for (var i = 0, ii = records.length; i < ii; ++i) {
layer = records[i].getOlLayer();
layer.on('propertychange', me.onChangeLayer, me);
me.bindLayer(layer, records[i]);
if (index === 0) {
me.layers.push(layer);
} else {
Expand Down Expand Up @@ -386,17 +423,13 @@ Ext.define('GeoExt.data.store.Layers', {
* @private
*/
onStoreUpdate: function(store, record, operation, modifiedFieldNames) {
var me = this;
if (operation === Ext.data.Record.EDIT) {
if (modifiedFieldNames) {
var layer = record.getOlLayer();
modifiedFieldNames.filter(function(field) {
// use only fields that are configured to synchronize
return record.synchronizePropertiesToMap
.indexOf(field) > -1;
}).forEach(function(field) {
var value = record.get(field);
if (value !== layer.get(field)) {
layer.set(field, value);
Ext.Array.forEach(modifiedFieldNames, function(prop) {
if (record.synchronizedProperties.indexOf(prop) > -1) {
me.synchronize(layer, record, prop);
}
});
}
Expand Down Expand Up @@ -489,6 +522,18 @@ Ext.define('GeoExt.data.store.Layers', {
me.loadRecords(records, append ? me.addRecordsOptions : undefined);
me.fireEvent('load', me, records, true);
}
}
},

/**
* This function synchronizes a value, but only sets it is different.
* @param {Ext.data.Model|ol.layer.Base} destination The destination.
* @param {Ext.data.Model|ol.layer.Base} source The source.
* @param {string} prop The property that should get synchronized.
*/
synchronize: function(destination, source, prop) {
var value = source.get(prop);
if (value !== destination.get(prop)) {
destination.set(prop, value);
}
}
});
42 changes: 33 additions & 9 deletions test/spec/GeoExt/data/store/Layers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,12 @@ describe('GeoExt.data.store.Layers', function() {

});

describe('synchronizePropertiesToMap', function() {
describe('synchronizedProperties', function() {
var map;
var layer;
beforeEach(function() {
layer = new ol.layer.Vector({
title: 'Initial title',
source: new ol.source.Vector({
features: [
new ol.Feature()
Expand All @@ -381,22 +382,38 @@ describe('GeoExt.data.store.Layers', function() {
});
});

it('reads properties on load', function() {
var store = Ext.create('GeoExt.data.store.Layers', {map: map});

var record = store.getAt(0);

expect(record.get('title')).to.eql('Initial title');
expect(record.get('other-prop')).to.equal(undefined);
});

it('by default it only synchronizes `title`', function() {
var store = Ext.create('GeoExt.data.store.Layers', {map: map});

var layerRec = store.getAt(0);
var olLayer = layerRec.getOlLayer();

layerRec.set('title', 'Kalle Berga');
layerRec.set('other-prop', 'Some Value');
layerRec.set('other-prop', 'Some value');

var olLayer = layerRec.getOlLayer();
expect(olLayer.get('title')).to.equal('Kalle Berga');
expect(olLayer.get('title')).to.eql('Kalle Berga');
expect(olLayer.get('other-prop')).to.equal(undefined);

olLayer.set('title', 'Some title');
olLayer.set('other-prop', 'Other value');

expect(layerRec.get('title')).to.eql('Some title');
expect(layerRec.get('other-prop')).to.eql('Some value');
});

it('synchronizes custom properties', function() {
Ext.define('CustomLayerModel', {
extend: 'GeoExt.data.model.Layer',
synchronizePropertiesToMap: ['other-prop']
synchronizedProperties: ['other-prop']
});

var store = Ext.create('GeoExt.data.store.Layers', {
Expand All @@ -405,12 +422,19 @@ describe('GeoExt.data.store.Layers', function() {
});

var layerRec = store.getAt(0);
var olLayer = layerRec.getOlLayer();

layerRec.set('title', 'Kalle Berga');
layerRec.set('other-prop', 'Some Value');
layerRec.set('other-prop', 'Some value');

var olLayer = layerRec.getOlLayer();
expect(olLayer.get('title')).to.equal(undefined);
expect(olLayer.get('other-prop')).to.equal('Some Value');
expect(olLayer.get('title')).to.eql('Initial title');
expect(olLayer.get('other-prop')).to.eql('Some value');

olLayer.set('title', 'Other title');
olLayer.set('other-prop', 'Other value');

expect(layerRec.get('title')).to.eql('Kalle Berga');
expect(layerRec.get('other-prop')).to.eql('Other value');
});

});
Expand Down

0 comments on commit 075a85c

Please sign in to comment.