diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md index 50f00c1f35..b03d2f346a 100644 --- a/changelog/upgrade-notes.md +++ b/changelog/upgrade-notes.md @@ -128,7 +128,7 @@ The non API `getChecksum` functions of the style is also removed. The `ol/source/Vector#clear()` method no longer triggers a reload of the data from the server. If you were previously using `clear()` to refetch from the server, you now have to use `refresh()`. -The `ol/source/Vector#refresh()` method now triggers a reload of the data from the server. If you were previously using the `refresh()` method to re-render a vector layer, you should instead call `ol/layer/Vector#changed()`. +The `ol/source/Vector#refresh()` method now removes all features from the source and triggers a reload of the data from the server. If you were previously using the `refresh()` method to re-render a vector layer, you should instead call `ol/layer/Vector#changed()`. #### Other changes diff --git a/src/ol/source/Source.js b/src/ol/source/Source.js index aeca1ba1bc..24dcbf0710 100644 --- a/src/ol/source/Source.js +++ b/src/ol/source/Source.js @@ -145,7 +145,7 @@ class Source extends BaseObject { } /** - * Refreshes the source. Data from the server will be reloaded. + * Refreshes the source. The source will be cleared, and data from the server will be reloaded. * @api */ refresh() { diff --git a/src/ol/source/Vector.js b/src/ol/source/Vector.js index b476191989..b4c26b076f 100644 --- a/src/ol/source/Vector.js +++ b/src/ol/source/Vector.js @@ -985,16 +985,25 @@ class VectorSource extends Source { /** - * Set the new loader of the source. The next loadFeatures call will use the + * Set the new loader of the source. The next render cycle will use the * new loader. * @param {import("../featureloader.js").FeatureLoader} loader The loader to set. * @api */ setLoader(loader) { - this.loadedExtentsRtree_.clear(); this.loader_ = loader; } + /** + * Points the source to a new url. The next render cycle will use the new url. + * @param {string|import("../featureloader.js").FeatureUrlFunction} url Url. + * @api + */ + setUrl(url) { + assert(this.format_, 7); // `format` must be set when `url` is set + this.setLoader(xhr(url, this.format_)); + } + } diff --git a/test/spec/ol/source/vector.test.js b/test/spec/ol/source/vector.test.js index f00da8a92c..fdb8d02f6b 100644 --- a/test/spec/ol/source/vector.test.js +++ b/test/spec/ol/source/vector.test.js @@ -148,6 +148,79 @@ describe('ol.source.Vector', function() { }); + describe('clear and refresh', function() { + + let map, source, spy; + beforeEach(function(done) { + source = new VectorSource({ + format: new GeoJSON(), + url: 'spec/ol/source/vectorsource/single-feature.json' + }); + const target = document.createElement('div'); + target.style.width = target.style.height = '100px'; + document.body.appendChild(target); + map = new Map({ + target: target, + layers: [ + new VectorLayer({ + source: source + }) + ], + view: new View({ + center: [0, 0], + zoom: 0 + }) + }); + map.once('rendercomplete', function() { + spy = sinon.spy(source, 'loader_'); + done(); + }); + }); + + afterEach(function() { + if (spy) { + source.loader_.restore(); + } + document.body.removeChild(map.getTargetElement()); + map.setTarget(null); + }); + + it('#refresh() reloads from server', function(done) { + expect(source.getFeatures()).to.have.length(1); + map.once('rendercomplete', function() { + expect(source.getFeatures()).to.have.length(1); + expect(spy.callCount).to.be(1); + done(); + }); + source.refresh(); + }); + + it('#clear() removes all features from the source', function(done) { + expect(source.getFeatures()).to.have.length(1); + map.once('rendercomplete', function() { + expect(source.getFeatures()).to.have.length(0); + expect(spy.callCount).to.be(0); + done(); + }); + source.clear(); + }); + + it('After #setUrl(), refresh() loads from the new url', function(done) { + source.loader_.restore(); + spy = undefined; + expect(source.getFeatures()).to.have.length(1); + const oldCoordinates = source.getFeatures()[0].getGeometry().getCoordinates(); + map.on('rendercomplete', function() { + expect(source.getFeatures()).to.have.length(1); + const newCoordinates = source.getFeatures()[0].getGeometry().getCoordinates(); + expect(newCoordinates).to.not.eql(oldCoordinates); + done(); + }); + source.setUrl('spec/ol/data/point.json'); + source.refresh(); + }); + }); + describe('when populated with 10 random points and a null', function() { let features; @@ -197,62 +270,6 @@ describe('ol.source.Vector', function() { }); - describe('clear and refresh', function() { - - let map, source, spy; - beforeEach(function(done) { - source = new VectorSource({ - format: new GeoJSON(), - url: 'spec/ol/source/vectorsource/single-feature.json' - }); - const target = document.createElement('div'); - target.style.width = target.style.height = '100px'; - document.body.appendChild(target); - map = new Map({ - target: target, - layers: [ - new VectorLayer({ - source: source - }) - ], - view: new View({ - center: [0, 0], - zoom: 0 - }) - }); - map.once('rendercomplete', function() { - spy = sinon.spy(source, 'loader_'); - done(); - }); - }); - - afterEach(function() { - source.loader_.restore(); - document.body.removeChild(map.getTargetElement()); - map.setTarget(null); - }); - - it('#refresh() reloads from server', function(done) { - expect(source.getFeatures()).to.have.length(1); - map.once('rendercomplete', function() { - expect(source.getFeatures()).to.have.length(1); - expect(spy.callCount).to.be(1); - done(); - }); - source.refresh(); - }); - - it('#clear() removes all features from the source', function(done) { - expect(source.getFeatures()).to.have.length(1); - map.once('rendercomplete', function() { - expect(source.getFeatures()).to.have.length(0); - expect(spy.callCount).to.be(0); - done(); - }); - source.clear(); - }); - }); - describe('#forEachFeatureInExtent', function() { it('is called the expected number of times', function() { @@ -570,7 +587,7 @@ describe('ol.source.Vector', function() { source.loadFeatures([-10000, -10000, 10000, 10000], 1, getProjection('EPSG:3857')); source.setLoader(loader2); - source.clear(); + source.refresh(); source.loadFeatures([-10000, -10000, 10000, 10000], 1, getProjection('EPSG:3857')); expect(count1).to.eql(1);