【问题标题】:Error when trying to render Google Map on page尝试在页面上呈现 Google 地图时出错
【发布时间】:2026-02-09 14:20:07
【问题描述】:

问题

我正在尝试使用 Angular 2 和 TypeScript 中的 API 创建 Google 地图的自定义实现。我已经完成了应该在页面上呈现地图的部分。

不幸的是,地图呈现为一个空白的灰色方块,并且尝试与之交互会导致一个非常不起眼的Cannot read property 'x' of undefined 错误。

我在网站上阅读了其他几个问题,这通常是由于地图试图渲染到隐藏的 DOM 元素中,加载到不存在的 DOM 元素中(不在页面加载函数中),或者它失去了对其渲染到的 DOM 元素的引用。

从我在这里看到的情况来看,我已经满足了所有这些条件,除非我错过了关于 Angular 在这里工作方式的一些东西?

有人可以在这里指出正确的方向吗?

代码

declare let google: any;

/**
 * @Component: Map
 * @Section: Miscellaneous
 * @Description: Generates an interactive map
 */
@Component({
    selector: 'mymap',
    template: `<div #map style="min-width:600px; min-height: 600px;"></div>`
})
export class MyMapComponent {

    // A reference to the map DOM element
    @ViewChild("map") mapEl: ElementRef;

    // A reference to the map object
    map: any;

    // Intializes the map
    initMap: Function = function(){

        // Set the map to a new google map
        this.map = new google.maps.Map(this.mapEl.nativeElement, {

            // Default zoom level
            zoom: this.zoomLevel | 6
        })

        console.log(this.map);
    };

    // Sets the center of the map
    setMapCenter: Function = function( latlng: any ){
        if ( this.map && latlng ){
            this.map.setCenter();
        }
    }

    // Callback for the call to the browser to request the users estimated lat/lng
    getUserLocationCallback: any = function( position: any ){

        // Catches a Geoposition object:
        // coords
        //  - accuracy
        //  - altitude
        //  - altitudeAccuracy
        //  - heading
        //  - latitude
        //  - longitude
        //  - speed
        // timestamp
        this.setMapCenter(new google.maps.LatLng({lat: position.coords.latitude, lng: position.coords.latitude}));
    }

    // On Init
    ngAfterViewInit(){

        // Set the key for the Google Maps API
        var gmap_api_key = "[KEY_REMOVED]";

        // Create the script tag and add it to the document
        var gmap = document.createElement('script');
        gmap.type = 'text/javascript';
        gmap.async = true;
        gmap.src = "https://maps.googleapis.com/maps/api/js?key=" + gmap_api_key;
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(gmap, s);

        // Wait for the script to load
        var mapsInterval = setInterval( () => {

            // If the script is loaded and the maps functions are available
            if ( typeof google !== "undefined" && google.maps && google.maps.Map){

                // Clear our interval
                clearInterval(mapsInterval);

                // Initialize the map
                this.initMap();

                // Request location from the browser. Arrow function used to maintain scope.
                navigator.geolocation.getCurrentPosition( () => { this.getUserLocationCallback } );
            }
        }, 0);
    }

    /**
     * @Property: displayedMarkers
     * @Description: A list of markers current displayed on the map.
     * @Type: array
     * @Two-way: output only
     */
    @Output() displayedMarkersChange: EventEmitter<any[]> = new EventEmitter;

    /**
     * @Property: mapCenter
     * @Description: lat/long of the center of the map being displayed
     * @Type: object {lat: "N", lng: "N"}
     * @Two-way: true
     */
    @Input()
    set mapCenter( position: any ){

        // If a position was provided
        if ( typeof position !== "undefined" ){

            // Set thet map center using the provided position
            this.setMapCenter( new google.maps.LatLng (position ) );
        }
    }
    @Output() mapCenterChange: EventEmitter<any[]> = new EventEmitter;

    /**
     * @Property: zoomLevel
     * @Description: Current zoom level of the map. Accepts values between 0 (shows the entire earth) and up 21
     * @Type: array
     * @Two-way: true
     */
    @Input() zoomLevel: number;
    @Output() zoomLevelChange: EventEmitter<number> = new EventEmitter;

    /**
     * @Property: filters
     * @Description: Filters to be applied to the marker results.
     * @Type: array
     * @Two-way: false
     */
    @Input() filters: any[];
} 

Plunkr

https://plnkr.co/edit/pIVOCSJ5eb1PUVXoEffS?p=preview

【问题讨论】:

标签: angular typescript google-maps-api-3


【解决方案1】:

首先,感谢您提供 google maps API 密钥 ;-)。

您的问题是谷歌地图在尝试与之交互时尚未加载。您需要提供回调以使其正常工作。

This question 可能会有所帮助。

【讨论】:

  • 仅供其他人阅读:关键是将回调手动添加到窗口:(&lt;any&gt;window).googleMapsReady = () =&gt; this.initMap();,将回调添加到 Google 地图 JS 的 URL:https://maps.googleapis.com/maps/api/js?callback=googleMapsReady&amp;key=,并确保地图初始化时有地图中心:center: new google.maps.LatLng(32.7767, 96.7970)
最近更新 更多