You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular16中Google Maps自定义HTML标记失效及构造函数错误求助

在Angular 16中使用Google Maps高级标记的问题

我按照Google官方文档在Angular16中创建带HTML内容的地图标记,但现在遇到两个问题:

  1. 应用仅生成默认标记,完全忽略自定义HTML内容
  2. 触发构造函数错误:

main.ts:6 ERROR TypeError: google.maps.Map is not a constructor
at google-maps.mjs:252:34
at _ZoneDelegate.invoke (zone.js:368:26)
at Zone.run (zone.js:129:43)
at NgZone.runOutsideAngular (core.mjs:10979:28)
at GoogleMap.ngOnInit (google-maps.mjs:251:26)
at callHookInternal (core.mjs:4024:14)
at callHook (core.mjs:4051:13)
at callHooks (core.mjs:4006:17)
at executeInitAndCheckHooks (core.mjs:3956:9)
at selectIndexInternal (core.mjs:11780:17)


相关代码

MapComponent.ts

import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-property-map',
  templateUrl: 'map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {
  ngOnInit() {
    this.initMap();
  }
  @ViewChild(MapComponent) infoWindow: MapComponent | undefined;
  property : any;

  
  constructor( ){}
  async initMap() {
    const  Map  = await google.maps.importLibrary("maps");

    const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
    const map = new Map(document.getElementById("map") as HTMLElement, {
    zoom: 11,
    center: { lat:-33.95719133500393,  lng: 25.600222789050612 },
    mapId: "4504f8b37365c3d0",
    });

    for (const property of this.properties) {
      const marker = new google.maps.Marker({
        map,
        position: property.position,
        title: property.description,
      });

      marker.addListener('click', () => {
        this.toggleHighlight(marker, property);
      });
    }
  }

  toggleHighlight(marker: google.maps.Marker, property: any) {
    if (marker.getZIndex() === 1) {
      marker.setZIndex(null);
      // Remove the highlight class or handle it based on your CSS classes
    } else {
      marker.setZIndex(1);
      // Add the highlight class or handle it based on your CSS classes
    }
  }
    
    buildContent(property: any) {
     const content = document.createElement("div");
     content.classList.add(property);
    content.innerHTML = ``
      
    return content;
  }

  
   properties = [{
    address: 'Allister Miller Dr, Walmer, Gqeberha, 6070',
    description: 'Airport Reservoir',
    price: '$ 3,889,000',
    type: 'building',
    size: 300,
    position: {
      lat: -33.9864000933515, 
      lng: 25.61399429260211,
    },

MapComponent.html

<div id="map" style="height: 500px;"></div>

<google-map>
    <div class="icon">
                            <i aria-hidden="true" class="fa fa-icon" [ngClass]="'fa-' + property.type" [title]="property.type"></i>
                            <span class="fa-sr-only">{{ property.type }}</span>
                              </div>
                              <div class="details">
                                  <div class="price">{{ property.price }}</div>
                                  <div class="address">{{ property.address }}</div>
                                  <div class="features">
                                      <div>
                                          <i aria-hidden="true" class="fa fa-bed fa-lg bed" title="bedroom"></i>
                                          <span class="fa-sr-only">bedroom</span>
                                          <span>{{ property.bed }}</span>
                                      </div>
                                      <div>
                                          <i aria-hidden="true" class="fa fa-bath fa-lg bath" title="bathroom"></i>
                                          <span class="fa-sr-only">bathroom</span>
                                          <span>{{ property.bath }}</span>
                                      </div>
                                      <div>
                                          <i aria-hidden="true" class="fa fa-ruler fa-lg size" title="size"></i>
                                          <span class="fa-sr-only">size</span>
                                          <span>{{ property.size }} ft<sup>2</sup></span>
                                      </div>
                                  </div>
                        </div>
</google-map>

问题解决方案

1. 修复google.maps.Map is not a constructor错误

错误原因是混用了Angular Google Maps组件(<google-map>标签)和原生Google Maps JS API初始化逻辑,两者冲突:

  • Angular Google Maps组件会自动初始化Map实例,不需要手动调用new Map()
  • 你重复导入了maps库,且同时用两种方式创建地图

解决步骤:

  • 移除initMap中的原生Map初始化代码,改用Angular组件的方式配置地图
  • 确保已正确安装并导入@angular/google-maps模块

修改后的组件核心代码:

import { Component, OnInit, ViewChild } from '@angular/core';
import { GoogleMap } from '@angular/google-maps';

@Component({
  selector: 'app-property-map',
  templateUrl: 'map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {
  @ViewChild(GoogleMap) map!: GoogleMap;
  mapOptions: google.maps.MapOptions = {
    zoom: 11,
    center: { lat:-33.95719133500393,  lng: 25.600222789050612 },
    mapId: "4504f8b37365c3d0",
  };

  async ngOnInit() {
    // 导入需要的Google Maps库
    await google.maps.importLibrary("maps");
    await google.maps.importLibrary("marker");
    this.createAdvancedMarkers();
  }

  createAdvancedMarkers() {
    for (const property of this.properties) {
      const content = this.buildContent(property);
      // 使用高级标记组件(支持自定义HTML)
      const marker = new google.maps.marker.AdvancedMarkerElement({
        map: this.map.googleMap, // 获取Angular组件包装的原生Map实例
        position: property.position,
        content: content,
      });

      marker.addListener('click', () => {
        this.toggleHighlight(marker, property);
      });
    }
  }

  // ... 其他方法保持不变或按需修改
}

2. 让自定义HTML标记生效

当前问题点:

  • 使用了不支持自定义HTML的普通google.maps.Marker,需改用AdvancedMarkerElement
  • buildContent方法的innerHTML为空,且classList.add(property)逻辑错误(应添加类名而非对象)
  • HTML中的<google-map>标签未正确绑定数据和标记

解决步骤:

  • 完善buildContent方法,生成正确的自定义HTML结构:
buildContent(property: any) {
  const content = document.createElement("div");
  content.classList.add('custom-marker'); // 添加自定义样式类

  content.innerHTML = `
    <div class="icon">
      <i aria-hidden="true" class="fa fa-icon fa-${property.type}" title="${property.type}"></i>
      <span class="fa-sr-only">${property.type}</span>
    </div>
    <div class="details">
      <div class="price">${property.price}</div>
      <div class="address">${property.address}</div>
      <div class="features">
        <div>
          <i aria-hidden="true" class="fa fa-bed fa-lg bed" title="bedroom"></i>
          <span class="fa-sr-only">bedroom</span>
          <span>${property.bed || 'N/A'}</span>
        </div>
        <div>
          <i aria-hidden="true" class="fa fa-bath fa-lg bath" title="bathroom"></i>
          <span class="fa-sr-only">bathroom</span>
          <span>${property.bath || 'N/A'}</span>
        </div>
        <div>
          <i aria-hidden="true" class="fa fa-ruler fa-lg size" title="size"></i>
          <span class="fa-sr-only">size</span>
          <span>${property.size} ft<sup>2</sup></span>
        </div>
      </div>
    </div>
  `;

  return content;
}
  • 修改HTML,移除无效的<google-map>子内容,绑定Angular组件属性:
<google-map 
  [options]="mapOptions"
  style="height: 500px;"
  #mapRef
></google-map>

额外注意事项

  • 在index.html中正确加载Google Maps JS API,需包含marker库:
    <script src="https://maps.googleapis.com/maps/api/js?key=你的API密钥&libraries=marker&v=weekly"></script>
    
  • 安装@angular/google-maps:npm install @angular/google-maps
  • 确保properties数组中的对象包含bed和bath字段,避免模板报错
  • 添加自定义CSS美化标记样式,防止标记显示异常

内容的提问来源于stack exchange,提问作者Keenan Burriss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 04:10:57