Javascript继承不适用于google.maps.OverlayView

时间:2012-10-02 20:48:34

标签: google-maps gwt javascript

编辑: 在这一天工作了一天后,我相信我知道发生了什么,但我还没有确认。一旦我确切知道,我会将其作为答案发布。

我很确定发生的事情是因为Google Maps API是通过AjaxLoader实用程序从GWT加载的,所以当加载包含USGSOverlay代码的javascript库时,google.maps.OverlayView没有被解析,所以这一行

USGSOverlay.ptototype=google.maps.OverlayView();

清除对象的原型信息。我现在正在努力在AjaxLoader.loadApi()方法完成后动态加载USGSOverlay库。

另一个症状:当原型设置为google.maps.OverlayView()时,它会破坏USGSOverlay的继承,以及我附加到文件底部的测试对象的继承。如果我通过将这些行添加到JS库文件的开头来更改我的USGSOverlay对象的继承,

function OverlayParent() {
}

OverlayParent.prototype.setMap= function(map) {}

并将我的 USGSOverlay.prototype 更改为等于 new OverlayParent()继承有效并且我没有得到异常 this.SetMap(map)是不是功能

如果某人有一个现成的解决方案,我会很感激链接,但我正在寻求类似于DOM-Based On-Demand Javascript的解决方案


我是Java Script的新手,但是一个非常有经验的程序员,这让我很难过。我一直在研究这项工作几天,进展甚微。在最新的版本中,我几乎完全复制Google Maps JavaScript API v3 CustomOverlay的代码。 OverlayView的相关文档声明“您应该通过将叠加层的原型设置为新的OverlayView.prototype来继承此类。”我真的不认为我遇到的问题是特定于Google地图的虽然API。这是代码。

function USGSOverlay(bounds, image, map) {
  // Now initialize all properties.
  this.bounds_ = bounds;
  this.image_ = image;
  this.map_ = map;

  // We define a property to hold the image's
  // div. We'll actually create this div
  // upon receipt of the add() method so we'll
  // leave it null for now.
  this.div_ = null;

  // Explicitly call setMap() on this overlay

  this.setMap(map);
}

USGSOverlay.prototype = new google.maps.OverlayView();
USGSOverlay.prototype.constructor=USGSOverlay;

如前所述,onAdd,draw和onRemove的示例实现。

单步调试代码一切正常,直到调用继承的方法setMap抛出以下异常:

Cannot load Google Maps API to your browser (TypeError): this.setMap is not a function;

Fire bug显示未设置 proto 变量。所以继承没有发生。我最初通过GWT JSNI函数调用构造函数,但为了消除这部分方程式,我编写了第二个测试Java Script对象来验证我传入的参数是否良好。该功能如下所示:

function TestUSGSOverlay(map,inBound) {
  var swBound = new google.maps.LatLng(39.5, -106.0);
  var neBound = new google.maps.LatLng(40.0, -105);
  var bounds = new google.maps.LatLngBounds(swBound, neBound);
  var sw = inBound.getSouthWest();
  var ne = inBound.getNorthEast();

  var marker = new google.maps.Marker({
      position: sw,
      map: map,
      title:"South West Corner"
  });

  var marker2 = new google.maps.Marker({
      position: ne,
      map: map,
      title:"North East Corner"
  });

  // Photograph courtesy of the U.S. Geological Survey
  var srcImage = 'images/DenverWest.png';
  var usgsMap = new google.maps.GroundOverlay(srcImage,bounds);
  usgsMap.setMap(map);
  this.overlay = new USGSOverlay(bounds, srcImage, map);
 }

如果我在最后一行注释掉地图显示在美国地质调查地图的西南和东北标记之间。我的实际要求是在表格div中显示一些文本,但为了尽可能地模仿,我替换了地图扫描。

我已经阅读了关于原型继承的一些帖子,我知道这是一个非常微不足道的主题,但我尝试过的任何事情都没有了。我在IE 8中得到的行为与在firefox中的行为相同。我非常感谢您提出的任何建议,我的想法已经不多了。

3 个答案:

答案 0 :(得分:0)

我终于能够诊断出这个问题并予以纠正。问题类似于竞争条件,但我不愿意这样说,因为正确的顺序永远不会发生。

问题是,在我正在处理的应用程序中,Google Maps API是通过Google API的AjaxLoader对象加载的,我的USGSOverlay javascript库是作为页面加载过程的一部分加载的。 AjaxLoader从GWT入口点方法或HTML世界onLoad中异步加载Google Maps API,这是在加载javascript之后发生的。没有报告错误,并且USGSOverlay的javascript构造函数存在,但是对象的继承不正确。 (作为一个旁白,任何人都可以推荐能够检测到这种情况的工具吗?)

在firebug调试器中可以看到无效的继承状态,因为USGSOverlay对象没有__proto__成员变量。为了解决这个问题,我添加了逻辑,将USGSOverlay javascript库动态加载到onLoad回调方法,该方法被传递到AjaxLoader的loadApi方法。然后唯一剩下的问题是这种方法依赖于DOM来检测页面头部的添加,并执行脚本加载。这反过来导致了真正的竞争条件,当程序试图访问它时,经常没有加载库。

这是一篇描述我如何动态加载java脚本的文章的链接。 DOM Based on Demand Javascript

为了解决未加载库的竞争条件,我只需添加一个

if (typeof USGSOverlay != 'undefined') { ... }

在调用new USGSOverlay(...方法之前进行测试。由于我的实际OverlayView派生对象与悬停有关,因此这个简单的预防性异常保护足以满足我的目的。如果您的Overlay是初始显示的一部分,则需要更复杂的方法,但这是您的问题:)。关于如何做到这一点有很多讨论。

答案 1 :(得分:0)

我遇到了同样的问题,但我不喜欢按照你在答案中描述的方式动态加载自定义叠加脚本的想法。

您如何调用initialize()函数?

我正在加载Google Maps API,如下所示:

<!-- I omitted sensor=false so this would fit without scrollbars -->
<script type="text/javascript" 
    src="http://maps.googleapis.com/maps/api/js?callback=initialize">
</script>

请注意 callback=initialize。这就是导致竞争状况的原因。我从获取API的查询字符串中删除了callback=initialize,并将其添加到 init.js 脚本的底部:

window.onload = initialize();

这解决了我。希望这有帮助!

答案 2 :(得分:0)

所以根据documentation,Google图表于2016年2月23日发布,是当前正式发布的版本。

This is what I found that needed to be updated

我希望这有帮助!

干杯, 杰