Meteor.js и Google Карты

я уже включил API карт в свой проект. Теперь я хочу показать некоторые маркеры на моей карте. Я инициализирую свою карту в функции запуска:

Meteor.startup(function() {
...
var mapOptions = {
  zoom: 8,
  mapTypeId: google.maps.MapTypeId.ROADMAP
};

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

Затем я установил центр карты при рендеринге.

Template.mapPostsList.rendered = function() {
var p2 = Session.get('location');

Map.setCenter(new google.maps.LatLng(p2.lat, p2.lng));
var marker = new google.maps.Marker({
    position: new google.maps.LatLng(p2.lat, p2.lng),
    title:'Meine Position'
  });
marker.setMap(Map);   

До сих пор все работает нормально. Несмотря на то, что у меня есть PostCollection, который содержит некоторые координаты для меня. У меня есть функция публикации и подписки. Теперь я хочу показывать свои посты с помощью маркеров на карте.

Моей первой идеей было сделать это в моей отображаемой функции. Проблема в том, что при начальной загрузке сообщения не отображаются, потому что моя локальная коллекция (клиентская сторона) не содержит сообщений. Загрузка постов с сервера занимает некоторое время.

Вот почему я попытался создать вспомогательную функцию. Потому что помощник автоматически перезагружается, если что-то в моих сообщениях меняется.

Template.mapPostsList.helpers({
posts: function() {
   var allPosts = Posts.find();
   allPosts.foreach(function(post) {
      create marker and attach it to the map
      ....
      marker.setMap(Map);
   })

Проблема в том, что моя переменная карты не определена. Есть ли способ определить его в глобальной области видимости? Почему я могу использовать свою переменную карты в моей отображаемой функции? Несмотря на то, что мне не нравится мой подход к внедрению моих маркеров с помощью вспомогательной функции, или это обычный способ?

Может ли кто-нибудь дать мне подсказку, как решить мою проблему?


person chaosbohne    schedule 26.05.2013    source источник


Ответы (2)


Как и в моем вопроснике, мне нужна была помощь для интеграции функций Google Maps. На этот вопрос до сих пор не было ответа, и я хочу, чтобы вы кратко рассказали, как решить эту проблему.

Как интегрировать карты в meteor.js/meteorite.js?

Сначала вы должны включить скрипт карт в свой тег заголовка.

<head>
  ....
  <title>Meteor and Google</title>
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">   </script>
</head>

Затем вы должны создать карты-Шаблон:

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

В связанном js-файле вы должны определить отображаемую функцию. Когда вызывается визуализированная функция, вы создаете карту и показываете маркер на карте. (Не забудьте дать вам карту css)

Template.mapPostsList.rendered = function() {  
  var mapOptions = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

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

  var p2 = Session.get('location');

  map.setCenter(new google.maps.LatLng(p2.lat, p2.lng));
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(p2.lat, p2.lng),
    title:'Meine Position',
    icon:'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'
  });
  marker.setMap(map);   

  Session.set('map', true);
};

Теперь объект карты воссоздается каждый раз при рендеринге шаблона. Это не лучшая практика, но она работает. Я попытался поместить создание в Template.mapPostsList.created-callback, но он всегда вызывает ошибку ширины смещения. Затем я устанавливаю маркер с моей позицией на карту и определяю сеанс, в котором моя карта инициализируется.

Хорошо. Но теперь моя сессия инициализируется при первом рендеринге, поэтому я устанавливаю для нее значение false, когда мой шаблон уничтожается.

Template.mapPostsList.destroyed = function() {
  Session.set('map', false);
};

Если вы хотите получать свои сообщения на карту, вы должны определить функцию автозапуска.

Deps.autorun(function() {

  var isMap = Session.get('map');
  if(isMap) {
    var allPosts = Posts.find();
    allPosts.forEach(function (post) {
      var marker = new google.maps.Marker({
        position: new google.maps.LatLng(post.location.lat, post.location.lng),
        title: post.title,
        postId: post._id
      });
      marker.setMap(map);
    });    
  }
});

Функция Deps.autorun всегда запускается при изменении содержимого. Это означает, что если я изменю переменную карты, связанную с сеансом, будет вызван автозапуск. Если я установлю для него значение false, я ничего не сделаю. В противном случае я получаю все свои сообщения на карту в forEach. Из-за воссоздания карты при рендеринге мне не нужно проверять, какие сообщения уже отмечены на карте, когда моя коллекция изменяется.

Это решение работает очень хорошо для меня.

Я надеюсь, что я могу кому-то помочь с этим!

person chaosbohne    schedule 28.05.2013
comment
Я получаю сообщение об ошибке Google не определено, хотя я включил тег script в заголовок и выполнил ваши действия, есть идеи? - person Kjellski; 14.07.2013
comment
Может быть, если у вас есть пример для меня;) - person chaosbohne; 30.07.2013
comment
Извините, я давно ушел из темы и не мог наверстать упущенное. Виноват. - person Kjellski; 06.08.2013

Что сработало для меня, так это следующее:

  1. Включите тег script на голове, чтобы загрузить карты Google.
  2. Включите еще один тег скрипта, который сообщает Google Maps, что делать (инициализировать) после загрузки окна.
  3. Поместите функцию, которая загружает карту в div в файле метеора js.

Вот код

map.html

<head>
  <title>cls</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key={YOUR_KEY}&sensor=false"></script>
  <script type="text/javascript">
    google.maps.event.addDomListener(window, 'load', initialize);
  </script>
</head>

<body>
  {{> map}}
</body>

<template name="map">
  <!-- Make the div#map-canvas have a height through css or it won't be shown -->
  <div id="map-canvas"/>
</template>

map.js

initialize = function() {
    var mapOptions = {
      center: new google.maps.LatLng(-34.397, 150.644),
      zoom: 8,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}

Надеюсь, поможет

person Jonathan Morales Vélez    schedule 31.08.2013
comment
Эй, я попробовал это, и я не уверен, что это сработало, потому что карта не отображается. Когда я открываю консоль, она говорит Uncaught TypeError: Cannot read property 'offsetWidth' of null и указывает на строку 7 файла javascript (map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);). У вас есть идеи, как это исправить? - person 2016rshah; 01.08.2014