麻烦包装谷歌地图 - 无法阅读财产' x'未定义的

时间:2017-06-28 15:10:26

标签: javascript google-maps

我试图将Google Maps Javascript API包装在Javascript类中,我可以在我的webapp中的多个位置重复使用。底部的代码包含概念的基础知识。一旦我开始工作,我就会在My.Map类中添加更多逻辑,以便从我的API中自动添加标记等。

我们的想法是,包含一个或多个地图的页面底部会有一个类似的脚本。

<script>
  $(function () {
    var map1 = new My.Map('#map1Canvas', { zoom: 10 });
    var map2 = new My.Map('#map2Canvas');
    My.Map.renderAll('MyGoogleMapsApiKeyGoesHere');
  }); 
</script>

当我运行此代码时,DIV会被部分初始化 - 获取边框和灰色背景。但是,它们没有完全初始化,当我点击或拖动它们时,我在控制台中收到错误。

Uncaught TypeError: Cannot read property 'x' of undefined

在各个地方添加console.log()语句告诉我,Google Maps API的标记动态插入正在运行,并且正在运行Map._renderAllCallback()。我还看到为两个实例中的每个实例调用了一次google.maps.Map()。如果我只启动其中一个(即注释掉&#34; var map2 = ...&#34;行),我会得到相同的结果。

我出错的任何想法?

&#34;我的&#34;的代码图书馆在下面。

(function(global) {

    Map._maps = {};

    function Map(selector, opts) {
        this.selector = selector;
        this.opts = opts || {};
        this.gmaps = []; 
        if (selector in Map._maps) {
            throw new Error("Duplicate My.Map selector; \""+selector+"\"!");
        }
        Map._maps[selector] = this;
    }   

    Map.prototype = {
        selector: null,
        opts: {}, 

        constructor: Map,

        _render: function() {
            var that = this 
            $(this.selector).each(function(idx, el) {
                that.gmaps.push(new google.maps.Map(el, that.opts));
            }); 
        }   
    };

    Map.renderAll = function(mapsKey) {
        if (!mapsKey) { throw new Error("Missing Google Maps API Key!"); }
        var script = $('<script>', {
            type: 'text/javascript',
            src: 'https://maps.googleapis.com/maps/api/js?key='
                 + mapsKey + '&callback=My.Map._renderAllCallback'
        });
        script[0].setAttribute('async', '');
        script[0].setAttribute('defer', '');
        $(document.body).append(script);
    };

    Map._renderAllCallback = function() {
        console.log("Callback() _maps", Map._maps);
        for (var key in Map._maps) {
            if (Map._maps.hasOwnProperty(key)) {
                console.log("Callback() key", key, Map._maps[key]);
                Map._maps[key]._render();
            }
        }
    };

    global.My = {
        Map: Map,
    };

})(this);

1 个答案:

答案 0 :(得分:0)

您没有正确初始化地图。有两个必需参数:zoomcenter。您可以使用fitBounds操作或使用自动缩放地图并使地图居中的对象(如DirectionsService或KmlLayer等)进行初始化。

这对我有用:

$(function () {
  var map1 = new My.Map('#map1Canvas', { zoom: 10, center: {lat: 45, lng:-72 } });
  var map2 = new My.Map('#map2Canvas', { zoom: 10, center: {lat: 45, lng:-112 } });
  My.Map.renderAll();
}); 

proof of concept fiddle

代码段

(function(global) {

  Map._maps = {};

  function Map(selector, opts) {
    this.selector = selector;
    this.opts = opts || {};
    this.gmaps = [];
    if (selector in Map._maps) {
      throw new Error("Duplicate My.Map selector; \"" + selector + "\"!");
    }
    Map._maps[selector] = this;
  }

  Map.prototype = {
    selector: null,
    opts: {},

    constructor: Map,

    _render: function() {
      var that = this
      $(this.selector).each(function(idx, el) {
        that.gmaps.push(new google.maps.Map(el, that.opts));
      });
    }
  };

  Map.renderAll = function(mapsKey) {
    // keys not currently required on SO or jsfiddle
    // if (!mapsKey) { throw new Error("Missing Google Maps API Key!"); }
    var script = $('<script>', {
      type: 'text/javascript',
      src: 'https://maps.googleapis.com/maps/api/js?callback=My.Map._renderAllCallback'
    });
    script[0].setAttribute('async', '');
    script[0].setAttribute('defer', '');
    $(document.body).append(script);
  };

  Map._renderAllCallback = function() {
    for (var key in Map._maps) {
      if (Map._maps.hasOwnProperty(key)) {
        Map._maps[key]._render();
      }
    }
  };

  global.My = {
    Map: Map,
  };

})(this);
html,
body,
{
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#map1Canvas {
  width: 400px;
  height: 400px;
}

#map2Canvas {
  width: 400px;
  height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="map1Canvas"></div>
<hr/>
<div id="map2Canvas"></div>
<script>
  $(function() {
    var map1 = new My.Map('#map1Canvas', {
      zoom: 10,
      center: {
        lat: 45,
        lng: -72
      }
    });
    var map2 = new My.Map('#map2Canvas', {
      zoom: 10,
      center: {
        lat: 45,
        lng: -112
      }
    });
    My.Map.renderAll();
  });
</script>