1

我有一个名为 map.html 的页面,它是一个使用 google maps api 的简单 html:

<head>
    <script type="text/javascript"
            src="https://maps.googleapis.com/maps/api/js?key=XXXXXXX&sensor=true&region=IL">
    </script>
    <script src="map.js" type="text/javascript"></script>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
</head>
        <body>

        </body>
<template name="map">
    <div id="map-canvas"></div>
</template>

我使用 Iron-router 路由到这个页面:

this.route("map");

也使用 pathFor:

<a href="{{pathFor 'map'}}" class="map"><div class="inner">set location</div></a></div>

最后,我的谷歌地图初始化函数位于名为 map.js 的单独文件中:

$(document).ready(function () {

    function initialize() {
        var TLV = new google.maps.LatLng(32.06461, 34.777222);
        var mapOptions = {
            zoom: 12,
            center: TLV,
            panControl: false,
            zoomControl: false,
            mapTypeControl: true,
            scaleControl: false,
            streetViewControl: false,
            overviewMapControl: true,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

        marker = new google.maps.Marker({
            position: TLV,
            map: map,
            title: 'Hello World!',
            draggable: true
        });

        google.maps.event.addListener(marker, 'dragend', function (evt) {
            var pos = [marker.getPosition().lat(), marker.getPosition().lng()];
            console.log(pos);
        });
    }
    google.maps.event.addDomListener(window, 'load', initialize);
});

如果您手动路由到 http:localhost/map 一切正常,但是如果您从 localhost 转到该路由的链接以映射其不起作用,现在我知道流星在启动时为所有文件提供服务,问题是如何防止它?或者如何将某个文件提供给特定页面?

4

1 回答 1

6

您没有考虑 Meteor 方式:Meteor 将您的所有 HTML 和 JS 资源捆绑到客户端(因此 Meteor 应用程序在首次加载时的初始启动时间很慢,这可能会在稍后解决)。这意味着您放入 head 和 body 标签中的所有内容最终都会合并,没有“页面”概念将 head 和 body 分开。您也不应该以传统方式包含第三方代码,从 head 标签中删除所有资源。您应该将自己的代码(map.js)放在“client/js/”中,将您的库放在“client/compatibility/”中,它们将被捆绑并发送到客户端。

现在发生的事情是您的 map.js 代码在 document.ready 上以传统的 jQuery 方式执行,这在 Meteor 应用程序中只发生一次,因为我们正在谈论一个单一网页应用程序。但是,当您导航到“/”时,当正确的 DOM 尚不存在时会执行此代码,并且当您导航到“/map”时,代码不会重新执行,这就是它失败的原因。

要解决此特定问题,请执行以下操作:

首先,您应该使用 {{#constant}} 指令围绕您的地图画布。

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

这将告诉 Meteor 不要重新渲染此块助手中的任何内容:它不会与不需要响应和重新渲染的 Google Maps 小部件混淆。如果您不这样做,每当页面中的响应式源更改并导致您的 DOM 刷新时,它可能会清除 map-canvas div 以用新的 div 替换它(这基本上就是重新渲染所做的)并破坏 Google Maps自己的东西。

然后将您的 Google 地图初始化代码放入 Template.map.rendered 回调中。

Template.map.rendered=function(){
    var initializeOnlyOnce=_.once(function(){
        // Google Maps initialization code goes here
    });
    initializeOnlyOnce();
};

为了确保它只会被 Template.map 渲染调用一次,我们使用 underscore.once ( http://underscorejs.org/#once )。您将不需要 addDomListener window.load 的东西,因为当这段代码运行时,页面已经加载,我们已经准备好立即执行 Google Maps 渲染。

告诉我它是否解决了您的问题,我尚未测试此代码,但这应该让您开始去哪里,因为目前您无法阻止 Meteor 在启动时提供所有文件,并提供特定文件到特定页面不是要走的路,因为 Meteor 中没有“页面”这样的概念。

目前这些事情相当乏味,但我听说新的 Meteor UI 会让它变得更简单。

于 2013-10-13T14:42:29.990 回答