如何在 @angular/google-maps infoWindow 中显示动态内容

Jas*_*son 13 google-maps angular-material angular

具体来说,如何在相应的信息窗口中显示与标记相关的信息?

通过遵循此处存储库上的示例,将为每个标记打开相同的信息。使用旧的角度谷歌地图,您可以轻松地将信息窗口插入标记内,并包含您想要的任何数据。

我看到了一些在模板中使用 {{ contentHere }} 设置内容的示例,但这只允许使用字符串。我需要像往常一样使用所有角度模板。

假设我们的模板类似于存储库示例:

<google-map height="400px"
        width="750px"
        [center]="center"
        [zoom]="zoom">
  <map-marker #marker
          *ngFor="let place of places"
          [position]="{ lat: place.latitude, lng: place.longitude }"
          [options]="markerOptions"
          (mapClick)="openInfoWindow(marker)">

      <map-info-window>
        <-- this is what i'm concerned with -->
        {{ place.description }}
      </map-info-window>
  </map-marker>
</google-map>
Run Code Online (Sandbox Code Playgroud)

然后我们像 repo 示例一样添加 viewchild 并以相同的方式打开它:

@ViewChild(MapInfoWindow, {static: false}) infoWindow: MapInfoWindow;

openInfoWindow(marker: MapMarker) {
  this.infoWindow.open(marker);
}
Run Code Online (Sandbox Code Playgroud)

虽然这确实打开了正确的标记,并且标记将反映动态信息,但这将为每个信息窗口显示相同的内容/地点.描述,这并不奇怪,因为正在使用单个 ViewChild。我想出了各种复杂的方法来做到这一点,并查看了源代码,但似乎没有一个明显的和/或内置的解决方案来在窗口中显示与内容相关的内容被标记者使用。没有将其作为基本示例似乎很奇怪。

你们中的任何人会如何去做这件事?

小智 13

最简单的方法,希望对你有帮助

TS

public openInfoWindow(marker: MapMarker, infoWindow: MapInfoWindow) {
    infoWindow.open(marker);
}
Run Code Online (Sandbox Code Playgroud)

超文本标记语言

<google-map *ngIf="mapOptions.center" width="100%" height="100%" [options]="mapOptions">
    <ng-container *ngFor="let elem of elements">
        <map-marker #marker="mapMarker" [position]="elem.position" [options]="elem.markerOptions" (mapClick)="openInfoWindow(marker, infoWindow)"></map-marker>
        <map-info-window #infoWindow="mapInfoWindow"> Content of {{ elem.id }} ...</map-info-window>
    </ng-container>
</google-map>
Run Code Online (Sandbox Code Playgroud)


Jas*_*son 12

使用ViewChildren,在模板中的for循环中使用索引,单击标记时传入索引,在forEach内部使用索引循环遍历所有ViewChildren(带有索引的for循环由于某种原因不会打开窗口),然后如果循环的索引与传入的索引匹配,打开该窗口。似乎有比这更好的方法,但这就是我在尝试了很多事情之后所能想到的:

在组件中:

@ViewChildren(MapInfoWindow) infoWindowsView: QueryList<MapInfoWindow>;

openInfoWindow(marker: MapMarker, windowIndex: number) {
  /// stores the current index in forEach
  let curIdx = 0;
  this.infoWindowsView.forEach((window: MapInfoWindow) => {
    if (windowIndex === curIdx) {
      window.open(marker);
      curIdx++;
    } else {
      curIdx++;
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

在模板中:

<google-map height="400px"
    width="750px"
    [center]="center"
    [zoom]="zoom">
  <map-marker #marker
      *ngFor="let place of places; let i = index" <-- added index -->
      [position]="{ lat: place.latitude, lng: place.longitude }"
      [options]="markerOptions"
      (mapClick)="openInfoWindow(marker, i)"> <-- pass in index -->

      <map-info-window>
        {{ place.description }}
      </map-info-window>
  </map-marker>
</google-map>
Run Code Online (Sandbox Code Playgroud)

这将打开带有相应标记的信息窗口。


小智 5

这里的大多数答案都是不正确的。任何一个

  1. 它们因未通过类型检查而存在缺陷(散列 id 指向 HTML 元素,而不是 MapMarker 类型,而且它们并不像 *ngFor 循环中包含的那样唯一)或
  2. 对性能有不好的影响(你不需要像MapMarkers一样多的InfoWindows,一个就够了)。

我最喜欢的是沃伦提出的解决方案。我的概念相似且简单

TS

@ViewChild(MapInfoWindow, { static: false }) infoWindow: MapInfoWindow;
@ViewChildren(MapMarker) markers: QueryList<MapMarker>;
points: PointMap[] = [];
infoContent: string = "";
options = {
    scrollwheel: false,
    disableDoubleClickZoom: true,
    maxZoom: 15,
    minZoom: 6,
};

ngOnInit() {
    // points: PointMap[] array is filled up here
}

openInfoWindow(windowIndex: number, content: string) {
    this.markers.forEach((marker: MapMarker, ix: number) => {
        if (windowIndex === ix) {
            this.infoContent = content;
            this.infoWindow.open(marker);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

我的PointMap类型(这些的数组或列表应该来自服务器端):

export class PointMap {
    title: string;
    position: any; // {lat, lng} object - in accordance to the API
    info: string; // HTML-formatted on server side in my case, but you may construct the content here from a number of plain string data
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<google-map [center]="center" width="100%" height="500px" [options]="options">
    <map-marker *ngFor="let marker of points; let ix = index
        [position]="marker.position" [title]="marker.title" 
        (mapClick)="openInfoWindow(ix, marker.info)">
    </map-marker>
    <map-info-window [innerHTML]="infoContent"></map-info-window>
</google-map>
Run Code Online (Sandbox Code Playgroud)

相信我,这确实有效。