I am trying to build an app based on Openlayers and backbone.js. Should i make each layer a view? So far i have a Map View, marker view and was thinking about making each layer a view as well. I have a markers model and map model. Can anyone help me out with setting this up?
After doing it similarly to @Gagan's answer in the past, here's how I would do it next time:
Treat the OpenLayers Map as a special rendering surface - different from the DOM, similar to how you would treat a <canvas>
. Recognize that Backbone makes some (light) assumptions around the idea that your views are rendered in the DOM:
There is a special relationship between Views and their corresponding DOM node ( view.el
and view.$el
magic).
The events
hash is automatically translated into handlers for events triggered on the DOM node.
We will want to recreate these concepts for our OpenLayers views. Some ideas:
This is one of the sticky parts of OpenLayers. Let's say you have a SelectControl
. You can listen to events at the layer level, which will give you a reference to event.feature
. But how do you map that feature back to your view to keep good separation of responsibilities? Pick your poison. In my examples below, I will (re)trigger the event directly on the feature, which the view already has a handle to. Then the view will have to listen to those events on the feature. Note that OL features don't have events built into them. We will mix Backbone events into them using _.extend(object, Backbone.Events);
.
Now for structuring your Views. I tend to think of an OpenLayers Layer
as a collection of items . Let's say you want to render a collection of features. You might create a FeatureCollectionView
class that is initialized with a Map
object. It would then create a Layer
for its collection.
FeatureCollectionView = Backbone.View.extend({
initialize: function(options) {
// requires options.map, an OpenLayers Map object.
// requires options.collection, a FeatureCollection object.
options = options || {};
this.map = options.map;
this.initLayer();
this.initSelectControl();
this.collection.on('add', this.addFeatureModel, this);
this.collection.on('remove', this.removeFeatureModel, this);
this.collection.each(this.addFeatureModel, this);
// ...
},
initLayer: function() {
this.layer = new OpenLayers.Layer.Vector('a collection of features', {/* options */});
this.map.addLayers([this.layer]);
},
initSelectControl: function() {
this.selectControl = new OpenLayers.Control.SelectFeature(this.layer, {
hover: true,
multiple: false,
highlightOnly: true
});
this.map.addControl(this.selectControl);
this.selectControl.activate();
this.layer.events.on({
featurehighlighted: function(event) {
// requires that you've extended your view features with Backbone.Events
if (event.feature.trigger) {
event.feature.trigger('featurehighlighted', event);
}
},
featureunhighlighted: function(event) {
// requires that you've extended your view features with Backbone.Events
if (event.feature.trigger) {
event.feature.trigger('featureunhighlighted', event);
}
},
scope: this
});
},
addFeatureModel: function(model) {
if (!this.views) this.views = {};
this.views[model.cid] = new FeatureItemView({
layer: this.layer,
model: model
});
},
removeFeatureModel: function(model) {
this.views && this.views[model.cid] && this.views[model.cid].remove();
},
// ...
});
Then we need a FeatureItemView
that is initialized with an OL Layer
to render itself on.
MyFeatureView = Backbone.View.extend({
initialize: function(options) {
// requires options.layer, an OpenLayers Layer that is already added to your map.
options = options || {};
this.layer = options.layer;
this.initSelectControl();
// ...
this.render();
_(this.feature).extend(Backbone.Events);
this.feature.on('featurehighlighted', this.showPopup, this);
this.feature.on('featureunhighlighted', this.hidePopup, this);
},
render: function() {
this.feature = // ...
this.layer.addFeatures([this.feature]);
// ...
},
remove: function() {
this.layer.removeFeatures([this.feature]);
},
// ...
});
I found some other interesting solutions by searching for discussions related to "backbone and canvas" since it has some similar aspects.
This gist may help you. For understanding Backbone with OpenLayers its quite useful. https://gist.github.com/bwreilly/2052314
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.