Java脚本继承不适用于google.maps.OverlayView



编辑:经过又一天的工作,我相信我知道发生了什么,但我还没有证实。一旦我确定了,我会把它作为一个答案发布。

我很确定发生的事情是,因为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.protype更改为等于new OverlayParent()继承有效,我没有得到异常this.SetMap(map)不是函数

如果有人对此有现成的解决方案,我将不胜感激,但我正在寻求类似于这种基于DOM的按需Javascript 的解决方案


我是Java脚本的新手,但我是一个经验丰富的程序员,这让我很困惑。我已经在这方面工作了几天,但进展甚微。在最新的版本中,我几乎完全复制了Google Maps JavaScript API v3 CustomOverlay中的代码。OverlayView的相关文档指出"您应该通过将覆盖的原型设置为新的OverlayView.prototype来继承此类。">不过,我真的不认为我遇到的问题是Google Maps 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错误显示proto变量未设置。所以遗产没有发生。我最初是通过GWTJSNI函数调用构造函数的,但为了消除等式的这一部分,我编写了第二个测试JavaScript对象来验证我传递的参数是否良好。这个函数看起来像这样:

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中显示一些文本,但为了尽可能地模仿,我用map扫描代替了它。

我读过很多关于原型继承的文章,我知道这是一个不平凡的主题,但我所尝试的一切都没有变得更接近。我在IE 8中得到的行为与在firefox中得到的相同。如果你能提供任何建议,我们将不胜感激,我已经没有主意了。

我终于能够诊断并纠正这个问题。这个问题类似于竞赛条件,但我不太愿意这么称呼它,因为永远不会出现正确的顺序。

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

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

下面是一篇文章的链接,该文章描述了我如何动态加载java脚本。基于DOM的需求Javascript

为了避开没有加载库的竞争条件,我只添加了一个

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

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

我也遇到了同样的问题,但我不喜欢采用您在回答中描述的方式动态加载自定义覆盖脚本。

您是如何调用initialize()函数的?

我加载的谷歌地图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();

这为我解决了问题。希望这能有所帮助!

因此,根据文档,谷歌图表于2016年2月23日发布,是当前的官方版本。

这就是我发现的需要更新的地方。

我希望这能有所帮助!

干杯,Jay

最新更新