谷歌地图infoWindow点击事件在Meteor中重新渲染地图画布

时间:2014-02-10 23:02:10

标签: google-maps-api-3 meteor

嘿我试图在我的MeteorJS项目中使用谷歌地图让谷歌地图在地图上显示所有客户,然后当你点击其中一个标记时显示一个infoWindow。

问题是,只要你点击标记,它就会从头开始重新渲染地图,我知道这与点击infoWindow时设置的Session变量的反应性有关。

有什么办法可以避免在会话变量发生变化时重新渲染地图?

感谢。

下面是我在项目中使用的JS和模板。

 <template name="customers_map">
 {{#constant}}
 <div id="mapWrapper">
    <div id="map-canvas"></div>
 </div>
 {{/constant}}
</template>

制作Google地图和标记的代码。

Template.customers_map.rendered = function() {

$("#map-canvas").height("400px");

if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(p) {
        Session.set("myLat", p.coords.latitude);
        Session.set("myLng", p.coords.longitude);
    });
}

Deps.autorun(function(){

    var mapOptions = {
        center: new google.maps.LatLng(Session.get("myLat"), Session.get("myLng")),
        zoom: 15,
        zoomControl: true,
        zoomControlOptions: {style: google.maps.ZoomControlStyle.SMALL},
        streetViewControl: false,
        mapTypeControl: false,
        scaleControl: true,
        mapTypeId: google.maps.MapTypeId.SMALL
    }

var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

var infowindow = new google.maps.InfoWindow({
  content: Template.customers_infoWindow()
  });

Customers.find().forEach(function(customer) {

    if (customer.loc != null) {
        var geo = customer.geoLocation();
        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(geo.lat, geo.lng),
            title: customer.name(),
            icon:'http://maps.google.com/mapfiles/ms/icons/green-dot.png'
        });

        marker.setMap(map);

        google.maps.event.addListener(marker, 'click', function() {
            Session.set("customerId", customer._id);
            infowindow.open(map,marker);
        });

    } else {
        console.log(customer.name() + " has no geoLocation");
    };

});

});

};

infoWindow模板

<template name="customers_infoWindow">
    <h1>{{record.name}}</h1>
</template>

和infoWindow模板的js

Template.customers_infoWindow.record = function() {
  return Customers.findOne({_id: Session.get("customerId")});
}

2 个答案:

答案 0 :(得分:1)

如果您创建全局googlemaps对象,则可以从任何位置访问其属性。 This article有一个很好的例子。 总体要点是:

  1. 使用initialize方法创建一个googlemaps类。在initialize方法结束时,为地图的存在设置会话变量。 (Session.set('map',true);)
  2. 通过调用Template.customers_map.rendered中的googlemap init方法调用创建googlemap对象。

答案 1 :(得分:0)

如果没有在我面前运行版本,确定有点困难,但我认为这主要是因为您将所有代码放在一个大的Deps.autorun块中。单击其中一个标记正在更改会话变量customerId,这将导致customers_infoWindow重新呈现(因为它显然是一个依赖项),但我确信这是预期的行为。

但是,由于您在var infoWindow块中声明Deps.autorun要将该模板的实例作为其属性之一,我认为更改customers_infoWindow实际上会使整个Deps.autorun计算,这意味着整个块将再次执行,包括var map = new google.maps.Map(...)行,它将基本上重新渲染地图(即使它不重新渲染包含的实际div元素它)。

因此,我建议将您的代码拆分为单独的Deps.autorun块,并确保同一块中的任何内容都应该同时重新运行 - 显然,这意味着Google Maps初始化代码和infoWindow处理程序应位于不同的块中。

重申一下,我认为这是正在发生的事情,但你必须尝试并告诉我......