如何把已弃用的 DeprecatedMapMarkerClusterer 迁移到 MapMarkerClusterer?
【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components
如果你的@angular/google-maps项目正在用<deprecated-map-marker-clusterer>标签做地图标记聚合,那么这个组件已经被官方标记为弃用:它基于旧的 MarkerClustererPlus 库(@googlemaps/markerclustererplus),源码注释中通过@breaking-change 21.0.0标注了它将在 21.0.0 版本移除。这篇文章基于仓库中的 README 与 CHANGELOG,给出从DeprecatedMapMarkerClusterer迁移到新MapMarkerClusterer组件(基于@googlemaps/markerclusterer)的完整路径:替换外部脚本、修改模板与导入、处理输入项差异,以及迁移后的验证方式。
背景:迁移前后各是什么
CHANGELOG.md在 19.0.0(2024-11-19)的 google-maps 破坏性变更中记录了这次重构的来龙去脉:
- 旧的
MapMarkerClusterer类被重命名为DeprecatedMapMarkerClusterer,map-marker-clusterer选择器被改成deprecated-map-marker-clusterer; - 同一版本引入了基于新库的新
MapMarkerClusterer组件,官方说明是"The new @googlemaps/markerclusterer API should be imported instead of the old one"。
两个组件的关键差异(分别来自 deprecated 组件 README、新组件 README 和 CHANGELOG.md):
| 对比项 | DeprecatedMapMarkerClusterer | MapMarkerClusterer |
|---|---|---|
| 模板标签 | <deprecated-map-marker-clusterer> | <map-marker-clusterer> |
| 底层库 | @googlemaps/markerclustererplus的MarkerClusterer类 | @googlemaps/markerclusterer的MarkerClusterer类 |
| 需要单独加载的脚本 | https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js | https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js |
| 可配置输入 | ariaLabelFn、averageCenter、batchSize、gridSize、imagePath、imageSizes、maxZoom、minimumClusterSize、styles、title、zIndex、zoomOnClick、options等 | renderer、algorithm |
| README 示例中的标记子元素 | <map-marker> | <map-advanced-marker> |
两个组件的输出(output)是一致的:clusteringbegin、clusteringend、clusterClick、markerClustererInitialized,因此现有的事件订阅代码不需要改动。
前置条件
按照 google-maps 组件 README 的要求,迁移前应确保:
- 项目已安装
@angular/google-maps(安装命令为ng add @angular/google-maps); index.html中按文档要求引入了 Google Maps 的 Dynamic Library Import 脚本并配置了 API Key;- MarkerClusterer 库与 Google Maps JavaScript API 一样,需要单独加载——它不包含在 Maps API 脚本里,两个 README 都强调了这一点。
第一步:替换 MarkerClusterer 外部脚本
在index.html(或你加载旧库的位置)中,把旧的 MarkerClustererPlus 脚本换成新库脚本:
<!-- 旧:基于 markerclustererplus --> <script src="https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js"></script> <!-- 新:基于 markerclusterer --> <script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>如果漏掉这一步,新组件在开发模式下初始化时会抛出文档中明确的错误(见"验证迁移是否生效"一节的第 1 条),这可以直接用来确认脚本是否加载正确。
第二步:替换模板标签与组件导入
deprecated 组件 README 中的旧用法示例:
<!-- 旧模板 --> <google-map height="400px" width="750px" [center]="center" [zoom]="zoom" (mapClick)="addMarker($event)"> <deprecated-map-marker-clusterer [imagePath]="markerClustererImagePath"> @for (position of markerPositions; track position) { <map-marker [position]="position" /> } </deprecated-map-marker-clusterer> </google-map>对应的新组件 README 示例:
<!-- 新模板 --> <google-map height="400px" width="750px" [center]="center" [zoom]="zoom" (mapClick)="addMarker($event)"> <map-marker-clusterer> @for (markerPosition of markerPositions; track $index) { <map-advanced-marker [position]="markerPosition"/> } </map-marker-clusterer> </google-map>组件类中的导入与imports数组同步替换(新 README 示例):
// google-map-demo.component.ts import {Component} from '@angular/core'; import {GoogleMap, MapMarkerClusterer, MapAdvancedMarker} from '@angular/google-maps'; @Component({ selector: 'google-map-demo', templateUrl: 'google-map-demo.html', imports: [GoogleMap, MapMarkerClusterer, MapAdvancedMarker], }) export class GoogleMapDemo { center: google.maps.LatLngLiteral = {lat: 24, lng: 12}; zoom = 4; markerPositions: google.maps.LatLngLiteral[] = []; addMarker(event: google.maps.MapMouseEvent) { this.markerPositions.push(event.latLng.toJSON()); } }注意两个 README 示例中标记子元素的差异:旧示例使用<map-marker>,新示例使用<map-advanced-marker>,迁移时按新示例调整。
第三步:处理输入项(input)差异
这是迁移中最容易出编译错误的一步,两边的可配置输入完全不同:
- 新组件没有旧组件的
imagePath、gridSize、imageSizes、zoomOnClick、options等输入,也不再提供fitMapToMarkers方法以及getGridSize()等一组 getter/setter 方法(这些只存在于 deprecated 组件源码 中)。模板里对这些输入的绑定要删除,或按新 API 重新实现。 - 新组件暴露两个输入(见 新组件源码):
renderer用于自定义聚合图标的渲染方式,algorithm用于指定聚合算法,两者均引用@googlemaps/markerclusterer库文档中的Renderer/Algorithm接口。 - 新组件 README 与旧 README 一样说明:
MapMarkerClusterer没有options输入,MarkerClusterer类的各项输入应直接设置。 - 源码注释表明:
renderer或algorithm在初始化之后发生变化时,组件会重建(recreate)内部的 cluster,而不是就地更新——如果你动态切换这两项,预期行为是重建。
事件侧无差异:clusteringbegin、clusteringend、clusterClick、markerClustererInitialized在两个组件上同名同义,订阅代码可原样保留。
验证迁移是否生效
仓库文档给出了以下可用于核对的具体判据:
脚本缺失时的开发模式报错。新组件在 map-marker-clusterer.ts 中会检查全局库是否存在,若不存在则抛出:
MarkerClusterer class not found, cannot construct a marker cluster. Please install the MarkerClusterer library: https://github.com/googlemaps/js-markerclusterer迁移后如果还能看到这条错误,说明新脚本没有加载成功;反过来,看不到这条错误说明库已正确加载。
markerClustererInitialized输出事件。底层MarkerClusterer对象创建完成后会发出该事件(new构造成功后立即emit)。订阅它可以在运行期确认聚合器已初始化。初始化前的访问保护。开发模式下,在聚合器完成初始化前尝试访问会抛出
Cannot interact with a MarkerClusterer before it has been initialized...,如果你的代码在markerClustererInitialized之前就调用聚合器相关逻辑,会出现这条错误。功能层面,新组件同样通过
@ContentChildren监听子标记的变化:标记增删后会自动调用addMarkers/removeMarkers并重绘(新组件对应方法为render())。README 示例中通过点击地图添加标记(mapClick事件)即可观察聚合是否正常工作。
限制与注意事项
- 弃用组件的移除计划在21.0.0(源码中的
@breaking-change 21.0.0标注),在此之前两者可以共存;如果你当前版本低于 19.0.0,则新组件尚不存在,需要先升级@angular/google-maps才能按本文迁移。 - 旧组件中通过
imagePath等输入定制的聚合图标外观,在新组件上没有同名输入,需改走renderer输入按@googlemaps/markerclusterer库的Renderer接口自行实现,文档未提供逐参数的对照映射。 - 两个组件的完整输入输出清单可分别对照 goldens/google-maps/index.api.md 中的
DeprecatedMapMarkerClusterer与MapMarkerClustererAPI 摘录核对。
主要参考文档:deprecated 组件 README、新组件 README、google-maps 组件 README、CHANGELOG.md。
【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考