简体   繁体   English

如何设置Openlayers以使用backbone.js?

[英]How can I set up Openlayers to use backbone.js?

I am trying to build an app based on Openlayers and backbone.js. 我正在尝试构建一个基于Openlayers和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: 在做了类似于@Gagan过去的回答之后,下面我将如何做到这一点:

Treat the OpenLayers Map as a special rendering surface - different from the DOM, similar to how you would treat a <canvas> . 将OpenLayers Map视为一个特殊的渲染表面 - 与DOM不同,类似于处理<canvas> Recognize that Backbone makes some (light) assumptions around the idea that your views are rendered in the DOM: 认识到Backbone围绕您在DOM中呈现视图的想法做出了一些(轻松的)假设:

  1. There is a special relationship between Views and their corresponding DOM node ( view.el and view.$el magic). 视图与其对应的DOM节点之间存在特殊关系( view.elview.$el magic)。

  2. The events hash is automatically translated into handlers for events triggered on the DOM node. events哈希自动转换为DOM节点上触发的事件的处理程序。

We will want to recreate these concepts for our OpenLayers views. 我们希望为OpenLayers视图重新创建这些概念。 Some ideas: 一些想法:

  1. In Backbone, the View is the mediator between a model and a piece of the DOM. 在Backbone中,View是模型和DOM的一部分之间的中介。 In OpenLayers, instead of a piece of the DOM, we have an OpenLayers Feature, Vector, Marker, Popup, whatever. 在OpenLayers中,我们有一个OpenLayers功能,Vector,Marker,Popup等,而不是一块DOM。 We could recreate this special relationship between the View and its OpenLayers object. 我们可以在View及其OpenLayers对象之间重新创建这种特殊关系。 The view listening to model changes and updating the OpenLayers object comes naturally. 听取模型更改和更新OpenLayers对象的视图很自然。 What about listening and responding to events on the OpenLayers object? 如何监听和响应OpenLayers对象上的事件?

This is one of the sticky parts of OpenLayers. 这是OpenLayers的一个棘手部分。 Let's say you have a SelectControl . 假设你有一个SelectControl You can listen to events at the layer level, which will give you a reference to event.feature . 您可以在图层级别收听事件,这将为您提供对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. 请注意,OL功能没有内置事件。 We will mix Backbone events into them using _.extend(object, Backbone.Events); 我们将使用_.extend(object, Backbone.Events);将Backbone事件混合到它们中_.extend(object, Backbone.Events); .

  1. You could create a featureEvents hash, but that might be over-engineering. 您可以创建一个featureEvents哈希,但这可能是过度工程。 Views already receive a model object and explicitly bind to its events. 视图已经接收到模型对象并显式绑定到其事件。 In my examples below, I'll do the same thing for the OL Feature that my view creates. 在下面的示例中,我将对我的视图创建的OL功能执行相同的操作。

Now for structuring your Views. 现在构建你的视图。 I tend to think of an OpenLayers Layer as a collection of items . 我倾向于将OpenLayers Layer视为一组项目 Let's say you want to render a collection of features. 假设您要渲染一组要素。 You might create a FeatureCollectionView class that is initialized with a Map object. 您可以创建使用Map对象初始化的FeatureCollectionView类。 It would then create a Layer for its collection. 然后它将为其集合创建一个Layer

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. 然后我们需要一个使用OL Layer初始化的FeatureItemView来自我渲染。

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. 要了解Backbone与OpenLayers,它非常有用。 https://gist.github.com/bwreilly/2052314 https://gist.github.com/bwreilly/2052314

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从ribs.js视图并使用Openlayers,我将如何与openlayers事件中的地图进行交互? - From a backbone.js view and using Openlayers, how would i interact with the map from a openlayers event? Backbone.js Visual Studio设置 - Backbone.js Visual Studio set up 如何在同一视图中的Openlayers事件中在bone.js视图中调用函数? - How do I call a function in my backbone.js view from my Openlayers event in that same view? 使用jsfiddle:如何使用underscore.js或ribs.js库? - Using jsfiddle: how can I use underscore.js or backbone.js libraries? 如何在Backbone.js中设置单个属性集(验证) - How can I do a single attribute set in Backbone.js (validation) 如何根据它的模型属性为Backbone.js视图动态设置className? - How can I dynamically set a className for a Backbone.js view based on it's model attributes? 如何在命名空间中使用ribs.js? - How do I use backbone.js with namespaces? 如何使用骨干.js将输入值发布到站点的其他区域? - How can I use backbone.js to post input values to other areas of a site? 如何在ASP.Net MVC中使用Backbone.js? - How can I use Backbone.js with ASP.Net MVC? 我该如何使用bone.js的多态性,尤其是super的属性? - How can I use backbone.js's polymorphism, especially super's attributes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM