流星谷歌地图自动完成只在多个模板上工作一次

Meteor Google Maps Autocomplete only works once on multiple templates

本文关键字:工作 一次 谷歌地图 流星      更新时间:2023-09-26

我正在使用带有 Meteor 的 Google Places 自动完成包,如果我让用户在一个模板中选择一个位置,自动完成功能将无法在其他模板中再次工作。

例如,如果用户为他们正在主持的活动选择自动完成位置,然后尝试在配置文件设置中设置其配置文件位置,则不会弹出自动完成位置。

事实上,如果他们甚至在一页上激活自动完成下拉菜单(甚至没有选择其中一个选项),它将无法在另一页上工作。

这是我的 HTML:

<template name="userUpdate">
      <script>
        window.onload = function() {
          var autocomplete = new google.maps.places.Autocomplete(
            (document.getElementById('autocomplete')),{types: ['geocode'] }
          );
        };
        </script>
        <form class="main form" autocomplete="off">
                <label class="control-label" for="location">Location</label>
                    <div class="controls">
                    <div id="locationField">
                    <input id="autocomplete" name="userLocation" class="form-control" autocomplete="off" placeholder="Where you live." type="text">
                </div>
                    </div>
      <p>
        <h4 id="setLocation">{{currentUser.profile.location}}</h4>
        <input id="updateUser" type="submit" class="btn btn-primary" value="Update Profile" />
      </p>
      </form>
    </template>

这是第二个模板:

<template name="postSubmit">
            <form class="main form" autocomplete="off">
                    <div class="form-group">
                    <label class="control-label" for="title">Event Name</label>
                        <div class="controls">
                            <input name="title" id="title" type="text" value="" placeholder="Event name" class="form-control"/>
                        </div>
                    </div>
                    <div class="form-group">
            <!--begin google test-->
        <script>
        window.onload = function() {
          var autocomplete = new google.maps.places.Autocomplete(
            (document.getElementById('autocompleteEventPost')),{types: ['geocode'] }
          );
        };
        </script>
                    <label class="control-label" for="location">Event Location</label>
                        <div class="controls">
                            <!--<input name="location" id="url" type="text" value="" placeholder="The location of the vent" class="form-control"/>-->
                        <div id="locationField">
                        <input id="autocompleteEventPost" name="location" autocomplete="off" placeholder="Event Location" type="text">
                    </div>
                        </div>
                    </div>
                <input type="submit" value="Submit" class="btn btn-primary"/>
            </form>
        </template>

我添加了mrt:googlemaps包,并设置了一个googlePlaces.js如下所示:

GoogleMaps.init({
'sensor': true, //optional
'key': '***my api key***', //optional
'language': 'en',  //optional
'libraries': 'places'
 });

值得注意的是,尽管自动完成在文件更新(服务器重新启动)后不再起作用,但它将在客户端刷新页面后再次工作。

基本上,我希望看到一个完美的例子,说明如何在 meteor.js 中的多个模板中使其工作。

谷歌地图的事情是,一旦你初始化,它只会将自己附加到当前的DOM实例上。当您切换到另一个页面/模板时,Gmaps 似乎失去了您刚刚创建的绑定,您必须正确重新初始化。

而且您正在使用只运行一次的window.onload..

查看如何将模板中找到的<script>代码移动到rendered模板事件:

var initAutoComplete = function() {
      var autocomplete = new google.maps.places.Autocomplete(
        (document.getElementById('autocompleteEventPost')),{types: ['geocode'] }
      );
};
Template.userUpdate.rendered = initAutoComplete;
Template.postSubmit.rendered = initAutoComplete;

不过,请确保您的时间安排正确。毕竟GoogleMaps API是异步的,甚至可能会搞砸这种初始化。为了避免这种情况,您可以做的一件事是将上述代码包装在GoogleMaps.init回调中。

然而,电耶稣的答案是有效的:必须为每个将使用 Google Places 自动完成 API 的元素声明一个变量。

他的解决方案:

var initAutoComplete = function() {
  var autocomplete = new google.maps.places.Autocomplete(
    (document.getElementById('autocompleteEventPost')),{types: ['geocode'] }
  );
};
Template.userUpdate.rendered = initAutoComplete;
Template.postSubmit.rendered = initAutoComplete;

有两个单独的输入字段,每个模板上一个。因此,您希望"地点自动完成"API 处理的每个输入字段都必须有一个变量。我将输入元素 ID 改回"autocomplete"。这是我的解决方案。请注意变量与输入字段的一对一比率。

    var initAutoComplete = function() {
      var autocomplete = new google.maps.places.Autocomplete(
        (document.getElementById('autocomplete')),{types: ['geocode'] }
      );
};
var initAutoCompletePost = function() {
      var autocomplete = new google.maps.places.Autocomplete(
        (document.getElementById('autocomplete')),{types: ['geocode'] }
      );
};
Template.userUpdate.rendered = initAutoComplete;
Template.postSubmit.rendered = initAutoCompletePost;

对于使用此解决方案的其他人,在我的工作实现中,我已经从我的 HTML 中删除了 <script> 标签(我的模板中不再有 javascript)。

我的猜测是您可能应该将其更改为class="autocomplete",id不应该重复,因此document.getElementById('autocomplete')将始终返回它找到的第一个元素。从未使用过谷歌地图,但我认为这可能是原因

其他答案对我来说都不起作用,所以我在单击文本输入时调用 initAutoComplete(),它对我来说效果更好。

Template.myTemplate.events({
   'click #autocomplete': function(e,template) {
     initAutoComplete();
   }
});
var initAutoComplete = function() {
  var autocomplete = new google.maps.places.Autocomplete(
    (document.getElementById('autocomplete')),{types: ['geocode'] }
  );
};

编辑:事实证明,效果不佳,不时得到这个:

Uncaught TypeError: Cannot read property 'Autocomplete' of undefined