谷歌地图有效,但没有任何地图显示?

时间:2015-11-20 00:59:16

标签: javascript google-maps google-maps-api-3 knockout-3.0

我已将Google地图嵌入到我的应用程序中。与地图交互有效。响应地图事件有效(地图zoom_changed,标记dragend等)。但是,只有地图的某些部分可见(例如标记和Google徽标),但地图本身不是(至少它们不会在95%的时间内出现)。

谁能告诉我这里发生了什么?

enter image description here

编辑:我将其用作KnockoutJS组件(与<gui-map></gui-map>一起插入)。源代码如下。我不相信KnockoutJS的使用与地图问题有关,因为:a)所有可观测量都正确连接并且100%的时间工作; 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 :我已成功通过将Map函数的整个主体(var self = this;赋值除外)包装在一个名为的匿名函数中来完成上述工作setTimeout()(延迟5000毫秒)。但是,无论如何,所有代码都会在DOMContentLoaded事件之后执行,因此我不确定这是一个问题。

1 个答案:

答案 0 :(得分:0)

问题的原因是,如果包含地图的元素不可见,则Google Maps Javascript API无法正确渲染地图。在我的情况下,地图位于隐藏的选项卡中。上面提到的超时解决了这个问题,因为延迟给了我足够长的时间来切换标签,然后才能执行调用Google Maps API的功能(如果我推迟打开标签,直到调用Google Maps API之后,问题就会重新出现表面)。

我通过在地图上手动触发调整大小并手动更新地图上的各种控件来解决此问题,例如:

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

我希望这个解决方案可以帮助其他人。