简体   繁体   English

谷歌地图可以使用但没有任何地图显示?

[英]Google Maps works but without any maps displaying?

I've embedded a Google Map into my application.我已将 Google 地图嵌入到我的应用程序中。 Interacting with the map works.与地图互动。 Responding to map events works (map zoom_changed , marker dragend , etc).响应地图事件有效(地图zoom_changed 、标记dragend等)。 However, only some parts of the map are visible (the marker and the Google logo for example), but the maps themselves are not (at least they don't appear 95% of the time).但是,只有地图的某些部分是可见的(例如标记和 Google 徽标),而地图本身则不可见(至少在 95% 的情况下它们不会出现)。

Can anyone tell me what's going on here?谁能告诉我这里发生了什么?

在此处输入图片说明

EDIT : I'm using this as a KnockoutJS component (inserted with with <gui-map></gui-map> ).编辑:我将其用作 KnockoutJS 组件(与<gui-map></gui-map>一起插入)。 The source code below.源代码如下。 I don't believe the use of KnockoutJS has anything to do with the map issues because: a) all the observables are wired up correctly and working 100% of the time;我不相信 KnockoutJS 的使用与地图问题有任何关系,因为:a) 所有的 observable 都正确连接并且 100% 的时间工作; and b) the map does work randomly without any code changes 5% of the time. b) 地图在 5% 的情况下会随机工作而没有任何代码更改。

define(['knockout', 'underscore'], function(ko, _){

    function Map(params, componentInfo) {
        var self = this;

        var defaultPosition = {lat:-25,lng:-130};
        var width = ko.isObservable(params.width) ? params.width : ko.observable(params.width ? params.width : '100px');
        var height = ko.isObservable(params.height) ? params.height : ko.observable(params.height ? params.height : '100px');
        var center = ko.isObservable(params.center) ? params.center : ko.observable(params.center ? params.center : defaultPosition);
        var zoom = ko.isObservable(params.zoom) ? params.zoom : ko.observable(params.zoom ? params.zoom : 12);
        var marker = ko.isObservable(params.marker) ? params.marker : ko.observable(params.marker ? params.marker : defaultPosition);

        var element = componentInfo.element;
        element.style.display = 'block';
        element.style.width = width();
        element.style.height = height();

        width.subscribe(function(){
            element.style.width = width();
        });

        height.subscribe(function(){
            element.style.height = height();
        });

        function onObservableCenterChanged(newValue){
            onObservableCenterChanged.changing = 1;
            console.log('updating center map');
            map.setCenter(newValue);
            setTimeout(function(){
                onObservableCenterChanged.changing = 0;
            }, 500);
        }
        center.subscribe(onObservableCenterChanged);

        function onObservableZoomChanged(newValue){
            onObservableZoomChanged.changing = 1;
            console.log('updating map zoom');
            map.setZoom(newValue);
            setTimeout(function(){
                onObservableZoomChanged.changing = 0;
            }, 500);
        }
        zoom.subscribe(onObservableZoomChanged);

        var map = new google.maps.Map(element, {
            center: center(),
            zoom: zoom()
        });

        var mapMarker = new google.maps.Marker({
            position:center(),
            map:map,
            title:'',
            draggable:true
        });

        map.addListener('center_changed', (function(){
            var mapCenterChangeTimeout;

            return function(){
                if (mapCenterChangeTimeout) {
                    clearTimeout(mapCenterChangeTimeout);
                }

                mapCenterChangeTimeout = setTimeout(function(){
                    if (!onObservableCenterChanged.changing) {
                        var newCenter = map.getCenter();

                        console.log('updating center observble');

                        center({
                            lat:newCenter.lat(),
                            lng:newCenter.lng()
                        });
                    }
                }, 500);
            };
        })());

        map.addListener('zoom_changed', (function(){
            var mapZoomChangedTimeout;

            return function(){
                if (mapZoomChangedTimeout) {
                    clearTimeout(mapZoomChangedTimeout);
                }

                mapZoomChangedTimeout = setTimeout(function(){
                    if (!onObservableZoomChanged.changing) {
                        console.log('updating zoom observable');
                        zoom(map.getZoom());
                    }
                }, 500);
            };
        })());

        mapMarker.addListener('dragend', function(){
            var newPosition = mapMarker.getPosition();
            marker({
                lat:newPosition.lat(),
                lng:newPosition.lng()
            });
        });
    }

    ko.components.register('gui-map', {
        template:{
            require:'text!components/gui/map.html'
        },
        viewModel:{
            createViewModel:function(params, componentInfo){
                return new Map(params, componentInfo);
            }
        }
    });

});

EDIT2 : I have succesfully got the above to work by wrapping the entire body of the Map function (with exception of the var self = this; assignment) in a anonymous function called with setTimeout() (with a delay of 5000 ms). EDIT2 :通过将Map函数的整个主体( var self = this;赋值除外)包装在一个使用setTimeout()调用的匿名函数中(延迟 5000 毫秒),我已经成功地使上述内容起作用。 However, all the code executes after the DOMContentLoaded event anyway, so I'm not sure why this is an issue.但是,无论如何,所有代码都在DOMContentLoaded事件之后执行,所以我不确定为什么会出现这个问题。

The cause of the problem was that the Google Maps Javascript API does NOT render the map correctly if the element in which the map is contained is not visible.问题的原因是,如果包含地图的元素不可见,则 Google Maps Javascript API 无法正确呈现地图。 In my situation, the map was located in a hidden tab.在我的情况下,地图位于隐藏选项卡中。 The timeout mentioned above solved the problem because the delay gave me long enough to switch tabs before the function that calls the Google Maps API could be executed (if I delayed opening the tab until after the Google Maps API was called, the issue would re-surface).上面提到的超时解决了这个问题,因为延迟给了我足够长的时间来在调用 Google Maps API 的函数可以执行之前切换选项卡(如果我延迟打开选项卡直到调用 Google Maps API 之后,问题将重新 -表面)。

I got around this issue by manually triggering a resize on the map, and manually updating the various controls on the map, eg:我通过在地图上手动触发调整大小并手动更新地图上的各种控件来解决此问题,例如:

google.maps.event.trigger(map, 'resize');
infoWindow.setContent(infoWindowElement);
infoWindow.close();
infoWindow.open(map, marker);

I hope this solution helps someone else.我希望这个解决方案可以帮助别人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM