Angular16中Google Maps自定义HTML标记失效及构造函数错误求助
在Angular 16中使用Google Maps高级标记的问题
我按照Google官方文档在Angular16中创建带HTML内容的地图标记,但现在遇到两个问题:
- 应用仅生成默认标记,完全忽略自定义HTML内容
- 触发构造函数错误:
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
相关产品推荐
相关产品推荐

