Google Maps 现在是 Angular 组件
获胜
新的 Angular 组件pearl-lullaby (v9.0.0-rc.0)引入了第二个官方@angular/component
组件:Google Maps 组件。
在本文中,我们将学习如何开始使用 Google Maps 组件。
今年早些时候,我们将此代码库的名称更改为“angular/components”,以强调我们
提供的不仅仅是 Material Design 组件的目标。9.0.0 版本包含了这方面的一项新功能——一个将Google Maps JavaScript API包装在一个易于使用的 Angular 组件中的
新软件包。
我非常期待团队能够扩展代码库来创建组件。
我们已经在v8.2.0中看到了一个YouTube Player
组件, Craig的文章中对此进行了探讨。
这些与现有 JavaScript API 的新集成使我们的工作变得更加轻松,
我很好奇即将发布的其他新组件!
设置
角度
可以从 安装 Google 地图模块@angular/google-maps
。
npm install @angular/google-maps
安装完成后,我们必须将 Angular 模块添加GoogleMapsModule
到import
声明中。
import { BrowserModule } from '@angular/platform-browser'
import { NgModule } from '@angular/core'
import { GoogleMapsModule } from '@angular/google-maps'
import { AppComponent } from './app.component'
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, GoogleMapsModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
导出GoogleMapsModule
我们可以使用的三个组件:
GoogleMap
:这是 Google 地图的包装器,可通过google-map
选择器获取MapMarker
:用于在地图上添加标记,可通过map-marker
选择器使用MapInfoWindow
:标记的信息窗口,可通过map-info-window
选择器访问
加载 Maps JavaScript API
我们还必须导入 Maps API,这可以通过在index.html
文件中添加脚本标签来完成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Map</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
</head>
<body>
<app-root></app-root>
</body>
</html>
要在生产环境中使用地图,您需要创建一个新的 API 密钥,请按照文档创建一个新密钥。
用法
谷歌地图
通过将 Google 地图组件添加到模板,我们就可以查看并使用 Google 地图了。
该地图将作为默认地图使用,并具有默认功能,例如,您可以放大、缩小地图并在地图中拖动。
<google-map></google-map>
输入属性
我们可以使用属性自定义默认地图的样式@Input()
。
最常用的属性已添加为@Input
属性,我们可以设置地图的大小、设置中心以及设置缩放级别。
财产 | 描述 |
---|---|
height |
设置初始高度 |
width |
设置初始宽度 |
center |
设置初始中心 |
zoom |
设置初始缩放 |
options |
设置选项,更多信息请参阅文档 |
为了充分利用 Google Maps API,我们还可以使用options
属性。
使用显式属性比使用 属性更胜一筹options
。
属性options
具有与 相同的接口Map Options interface
。
<google-map
height="500px"
width="100%"
[zoom]="zoom"
[center]="center"
[options]="options"
></google-map>
<!-- Use custom zoom buttons -->
<button (click)="zoomIn()">Zoom in</button>
<button (click)="zoomOut()">Zoom out</button>
export class AppComponent implements OnInit {
zoom = 12
center: google.maps.LatLngLiteral
options: google.maps.MapOptions = {
mapTypeId: 'hybrid',
zoomControl: false,
scrollwheel: false,
disableDoubleClickZoom: true,
maxZoom: 15,
minZoom: 8,
}
ngOnInit() {
navigator.geolocation.getCurrentPosition(position => {
this.center = {
lat: position.coords.latitude,
lng: position.coords.longitude,
}
})
}
zoomIn() {
if (this.zoom < this.options.maxZoom) this.zoom++
}
zoomOut() {
if (this.zoom > this.options.minZoom) this.zoom--
}
}
输出属性
该GoogleMap
组件将所有 Google Maps API 事件公开为@Output()
属性:
财产 | JavaScript API 方法 | 描述 |
---|---|---|
boundsChanged |
bounds_changed |
当视口边界发生变化时,会触发此事件 |
centerChanged |
center_changed |
地图中心属性改变时触发此事件 |
mapClick |
click |
当用户点击地图时触发此事件 |
mapDblclick |
dblclick |
用户双击地图时会触发此事件。请注意,在此事件之前,click 事件也会触发。 |
mapDrag |
drag |
当用户拖动地图时,此事件会重复触发 |
mapDragend |
dragend |
当用户停止拖动地图时触发此事件 |
mapDragstart |
dragstart |
当用户开始拖动地图时触发此事件 |
headingChanged |
heading_changed |
地图标题属性发生改变时触发此事件 |
idle |
idle |
地图平移或缩放后变为空闲状态时触发此事件 |
maptypeidChanged |
maptypeid_changed |
当 mapTypeId 属性发生改变时触发此事件 |
mapMousemove |
mousemove |
每当用户的鼠标移动到地图容器上时,就会触发此事件 |
mapMouseout |
mouseout |
当用户的鼠标退出地图容器时触发此事件 |
mapMouseover |
mouseover |
当用户的鼠标进入地图容器时触发此事件 |
projectionChanged |
projection_changed |
当投影发生变化时触发此事件 |
mapRightclick |
rightclick |
当地图容器上触发 DOM contextmenu 事件时,将触发此事件 |
tilesloaded |
tilesloaded |
当可见图块加载完成时触发此事件 |
tiltChanged |
tilt_changed |
地图倾斜属性改变时触发此事件 |
zoomChanged |
zoom_changed |
地图缩放属性改变时触发此事件 |
一篇文章涵盖所有这些事件可能过于冗长,本文我们将逐一介绍这些click()
事件。
如果您对所有事件感兴趣,我建议您参阅Google Maps API 文档,查看完整列表以及 Angular 源代码中的实现。
<google-map (mapClick)="click($event)"></google-map>
export class AppComponent implements OnInit {
click(event: google.maps.MouseEvent) {
console.log(event)
}
}
方法和 getter
如果我们通过使用装饰器保留对地图组件的引用@ViewChild
,我们还可以使用以下方法和 getter。
功能 | 描述 |
---|---|
fitBounds |
设置视口以包含给定的边界 |
panBy |
将地图中心改变给定的像素距离 |
panTo |
将地图中心更改为给定的 LatLng |
panToBounds |
将地图平移至包含给定 LatLngBounds 所需的最小量 |
getBounds |
返回当前视口的纬度/经度边界 |
getCenter |
返回地图中心显示的位置 |
getClickableIcons |
返回地图图标的可点击性 |
getHeading |
返回航空图像的罗盘航向 |
getMapTypeId |
返回地图类型 ID |
getProjection |
返回当前投影 |
getStreetView |
返回绑定到地图的默认StreetViewPanorama,可能是地图内嵌入的默认全景图 |
getTilt |
返回地图的当前入射角,以从视口平面到地图平面的度数为单位 |
getZoom |
返回当前缩放比例 |
controls |
附加到地图的附加控件 |
data |
绑定到地图的数据实例 |
mapTypes |
通过字符串 ID 注册 MapType 实例 |
overlayMapTypes |
可叠加的其他地图类型 |
例如,我们可以记录地图的当前中心。
export class AppComponent implements OnInit {
@ViewChild(MapInfoWindow, { static: false }) info: MapInfoWindow
logCenter() {
console.log(JSON.stringify(this.map.getCenter()))
}
}
地图标记
输入属性
地图设置好后,我们就可以开始添加标记了。
这可以通过使用MapMarker
组件来完成。
要添加标记,请确保标记位于google-map
标签内,否则将不会显示。
就像 一样MapControl
,最常用的选项可以直接通过@Input()
属性设置,但也可以使用 的完整选项集MapMarker
。
<google-map>
<map-marker
*ngFor="let marker of markers"
[position]="marker.position"
[label]="marker.label"
[title]="marker.title"
[options]="marker.options"
>
</map-marker>
</google-map>
export class AppComponent implements OnInit {
addMarker() {
this.markers.push({
position: {
lat: this.center.lat + ((Math.random() - 0.5) * 2) / 10,
lng: this.center.lng + ((Math.random() - 0.5) * 2) / 10,
},
label: {
color: 'red',
text: 'Marker label ' + (this.markers.length + 1),
},
title: 'Marker title ' + (this.markers.length + 1),
options: { animation: google.maps.Animation.BOUNCE },
})
}
}
该标记的完整规格:
财产 | 描述 |
---|---|
title |
设置标题,悬停时可见 |
position |
设置位置 |
label |
设置标签 |
clickable |
如果标记应该监听鼠标和触摸事件,则默认为true |
options |
设置选项,更多信息请参阅文档 |
输出属性
该MapMarker
组件还将 Google Maps API 事件作为@Output()
属性公开:
财产 | JavaScript API 方法 | 描述 |
---|---|---|
animationChanged |
animation_changed |
当标记的动画属性发生改变时,会触发此事件 |
mapClick |
click |
单击标记图标时会触发此事件 |
clickableChanged |
clickable_changed |
当标记的光标属性发生改变时,会触发此事件 |
cursorChanged |
cursor_changed |
当标记的光标属性发生改变时,会触发此事件 |
mapDblclick |
dblclick |
双击标记图标时触发此事件 |
mapDrag |
drag |
当用户拖动标记时,此事件会重复触发 |
mapDragend |
dragend |
当用户停止拖动标记时触发此事件 |
draggableChanged |
draggable_changed |
当标记的可拖动属性发生改变时,会触发此事件 |
mapDragstart |
dragstart |
当用户开始拖动标记时触发此事件 |
flatChanged |
flat_changed |
当标记的平面属性发生变化时,会触发此事件 |
iconChanged |
icon_changed |
当标记图标属性发生改变时,会触发此事件 |
mapMousedown |
mousedown |
当鼠标按下标记时触发此事件 |
mapMouseout |
mouseout |
当鼠标离开标记图标区域时触发此事件 |
mapMouseover |
mouseover |
当鼠标进入标记图标区域时触发此事件 |
mapMouseup |
mouseup |
当鼠标悬停在标记上时触发此事件 |
positionChanged |
position_changed |
当标记位置属性发生改变时,会触发此事件 |
mapRightclick |
rightclick |
右键单击标记时触发此事件 |
shapeChanged |
shape_changed |
当标记的形状属性发生变化时,会触发此事件 |
titleChanged |
title_changed |
当标记标题属性发生改变时,会触发此事件 |
visibleChanged |
visible_changed |
当标记的 visible 属性发生改变时,会触发此事件 |
zindexChanged |
zindex_changed |
当标记的 zIndex 属性发生改变时,会触发此事件 |
可以在Google Maps API 文档中找到对 API 的完整引用,并在源代码中找到 Angular 实现。
地图信息窗口
最后一个组件是MapInfoWindow
,它可以用来打开标记的弹出窗口。
要显示弹出窗口,我们必须在google-map
模板中添加该组件。
<map-info-window>Hello Google Maps</map-info-window>
上面的代码什么也没做,为了让它看起来就像点击标记时打开信息窗口一样。
我们将mapClick()
方法绑定到标记,并将标记引用传递给openInfo
方法以打开信息窗口。
<map-marker
#markerElem
*ngFor="let marker of markers"
[position]="marker.position"
[label]="marker.label"
[title]="marker.title"
[options]="marker.options"
(mapClick)="openInfo(markerElem)"
>
</map-marker>
MapInfoWindow
最后,我们在组件内部也有一个对组件的引用。
我们可以通过使用@ViewChild
装饰器来实现这一点。
有了信息窗口和标记的引用,我们就可以使用该infoWindow.open()
方法打开信息窗口了。
export class AppComponent implements OnInit {
@ViewChild(MapInfoWindow, { static: false }) infoWindow: MapInfoWindow
openInfo(marker: MapMarker, content) {
this.infoWindow.open(marker)
}
}
输入属性
财产 | 描述 |
---|---|
options |
设置选项,更多信息请参阅文档 |
输出属性
财产 | JavaScript API 方法 | 描述 |
---|---|---|
closeclick |
closeclick |
单击关闭按钮时触发此事件 |
contentChanged |
content_changed |
当内容属性发生改变时触发此事件 |
domready |
domready |
<div> 当包含信息窗口内容的附加到 DOM时,会触发此事件 |
positionChanged |
position_changed |
当位置属性改变时触发此事件 |
zindexChanged |
zindex_changed |
当信息窗口的 zIndex 发生变化时,会触发此事件 |
方法和 getter
通过使用infoWindow
具有对MapInfoWindow
组件的引用的属性,我们可以使用其以下方法和 getter
财产 | 描述 |
---|---|
close |
通过从 DOM 结构中移除此信息窗口来关闭它 |
getContent |
返回信息窗口的内容 |
getPosition |
返回信息窗口的位置 |
getZIndex |
返回信息窗口的 z 索引 |
open |
使用提供的 MapMarker 作为锚点打开 MapInfoWindow。如果未设置锚点,则使用选项输入的position属性。 |
动态内容
信息窗口内显示静态内容略显单调。
为了在信息窗口内提供动态内容,我们可以在组件内创建一个字符串属性,如下所示。
<map-info-window>{{ infoContent }}</map-info-window>
export class AppComponent implements OnInit {
@ViewChild(MapInfoWindow, { static: false }) infoWindow: MapInfoWindow
infoContent = ''
openInfo(marker: MapMarker, content) {
this.infoContent = content
this.infoWindow.open(marker)
}
}
可以在Google Maps API 文档中找到对 API 的完整引用,并在源代码中找到 Angular 实现。
整合起来
即将发布的 Angular 版本将为我们带来一系列积极的变化和全新的可能性。
我们早已翘首以盼 Angular v9 中的 Ivy 版本,现在我们也将共同期待 的新版本@angular/components
。
除了新功能之外MapComponent
,还将与 Angular CDK 中的剪贴板 API 进行集成,如使用新的 Angular Clipboard CDK 与剪贴板交互中所述。
Angular 组件非常新,因此文档和示例代码非常少。由于 Angular 的实现遵循 Google Maps API 规范,我们可以从 JavaScript API 中
查看丰富的文档。
请参阅下面的代码来了解此帖子的完整探索示例。
<google-map
height="500px"
width="100%"
[zoom]="zoom"
[center]="center"
[options]="options"
(mapClick)="click($event)"
>
<map-marker
#markerElem
*ngFor="let marker of markers"
[position]="marker.position"
[label]="marker.label"
[title]="marker.title"
[options]="marker.options"
(mapClick)="openInfo(markerElem, marker.info)"
>
</map-marker>
<map-info-window>{{ infoContent }}</map-info-window>
</google-map>
<button (click)="zoomIn()">Zoom in</button>
<button (click)="zoomOut()">Zoom out</button>
<button (click)="logCenter()">Log center</button>
<button (click)="addMarker()">Add marker</button>
import { Component, OnInit, ViewChild } from '@angular/core'
import { MapInfoWindow, MapMarker, GoogleMap } from '@angular/google-maps'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
@ViewChild(GoogleMap, { static: false }) map: GoogleMap
@ViewChild(MapInfoWindow, { static: false }) info: MapInfoWindow
zoom = 12
center: google.maps.LatLngLiteral
options: google.maps.MapOptions = {
zoomControl: false,
scrollwheel: false,
disableDoubleClickZoom: true,
mapTypeId: 'hybrid',
maxZoom: 15,
minZoom: 8,
}
markers = []
infoContent = ''
ngOnInit() {
navigator.geolocation.getCurrentPosition(position => {
this.center = {
lat: position.coords.latitude,
lng: position.coords.longitude,
}
})
}
zoomIn() {
if (this.zoom < this.options.maxZoom) this.zoom++
}
zoomOut() {
if (this.zoom > this.options.minZoom) this.zoom--
}
click(event: google.maps.MouseEvent) {
console.log(event)
}
logCenter() {
console.log(JSON.stringify(this.map.getCenter()))
}
addMarker() {
this.markers.push({
position: {
lat: this.center.lat + ((Math.random() - 0.5) * 2) / 10,
lng: this.center.lng + ((Math.random() - 0.5) * 2) / 10,
},
label: {
color: 'red',
text: 'Marker label ' + (this.markers.length + 1),
},
title: 'Marker title ' + (this.markers.length + 1),
info: 'Marker info ' + (this.markers.length + 1),
options: {
animation: google.maps.Animation.BOUNCE,
},
})
}
openInfo(marker: MapMarker, content) {
this.infoContent = content
this.info.open(marker)
}
}
在 Twitter 上关注我@tim_deschryver | 最初发布于timdeschryver.dev。
文章来源:https://dev.to/angular/google-maps-is-now-an-angular-component-2pjb