Ionic 4/5 - google 模态 window 地图与服务

Ionic 4/5 - google maps in modal window with a service

我正在使用 javascript SDK 在 Ionic 5 中显示地图。 我使用为此创建的服务加载这些地图。

当我在页面中执行时,一切都很好,但如果我将其中一个页面显示为模态,则地图不会加载,标记会将其放置在打开模态 window 的页面上在模态 window 本身。

让我们看看我能不能把代码放在下面,这样它就不会太“重”

home.page.html

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      HOME
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
    <div id="map"></div>
    <ion-button href = "page2" expand = "block">page 2</ion-button>
    <ion-button (click)="presentModal()" expand = "block" >page 3 modal</ion-button>
</ion-content>

page2.page.html

<ion-header>
  <ion-toolbar>
    <ion-title>page2</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
    <div id="map"></div>
    <ion-button href = "home" expand = "block" >home</ion-button>
</ion-content>

page3.page.html

<ion-header>
  <ion-toolbar>
    <ion-title>page3</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
    <div id="map"></div>
    <ion-button href = "home" expand = "block" >home</ion-button>
</ion-content>

home.page.ts

import { Component, OnInit }            from '@angular/core';
import { ModalController }              from '@ionic/angular';
import { LocationService }          from 'src/app/services/Location.service'
import { Page3Page }                    from 'src/app/pages/page3/page3.page';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
    constructor(public LocationService: LocationService,
                public ModalController: ModalController) {}

    ngOnInit () {
        this.LocationService.loadMap("home");
        }

    async presentModal() {
        const modal = await this.ModalController.create({
            component: Page3Page
            });
        return await modal.present();
        }
}

page2.page.ts

import { Component, OnInit } from '@angular/core';
import { LocationService }      from 'src/app/services/Location.service'

@Component({
    selector: 'app-page2',
    templateUrl: './page2.page.html',
    styleUrls: ['./page2.page.scss'],
    })
export class Page2Page implements OnInit {
    constructor(private LocationService: LocationService) {}

    ngOnInit () {
        //this.loadMap();
        this.LocationService.loadMap("page2");
        }
}

page3.page.ts

import { Component, OnInit } from '@angular/core';
import { LocationService }      from 'src/app/services/Location.service'

@Component({
  selector: 'app-page3',
  templateUrl: './page3.page.html',
  styleUrls: ['./page3.page.scss'],
})
export class Page3Page implements OnInit {
    constructor(private LocationService: LocationService) {}

    ngOnInit() {
        this.LocationService.loadMap("page3");
        }
}

location.service.ts

import { Injectable } from '@angular/core';

declare var google;

interface Marker {
    position: {
      lat: number,
      lng: number,
    };
    title: string;
  }

@Injectable({
  providedIn: 'root'
})
export class LocationService {

    map = null;

    constructor() { }

    loadMap(prmtrMapId) {
        // create a new map by passing HTMLElement
        const mapEle: HTMLElement = document.getElementById('map');
        var myLatLng, myTitle;
        var marker;
        // create LatLng object
        switch (prmtrMapId) {
            case "home": // No hay sentencia "break" en el 'case 0:', por lo tanto este caso también será ejecutado
                myLatLng = {lat: 54.1675272, lng: -7.5138625}; //england
                myTitle = "home -> England";
                break; // Al encontrar un "break", no será ejecutado el 'case 2:'
            case "page2":
                myLatLng = {lat: 51.713614, lng: 10.956151}; //deutschland 
                myTitle = "page2 -> Deutschland ";
                break;
            case "page3":
                myLatLng = {lat: 47.820012, lng: 3.490945}; //france
                myTitle = "page3 modal -> France";
                break;
            default:
                myLatLng = {lat: 4.658383846282959, lng: -74.09394073486328};
          }
       
        marker = {
            position: myLatLng,
            title: myTitle
            };

        // create map
        this.map = new google.maps.Map(mapEle, {
            center: marker.position,
            zoom: 4
            });

        google.maps.event.addListenerOnce(this.map, 'idle', () => {
            this.addMarker(marker);
        });
    }

    addMarker(marker: Marker) {
    return new google.maps.Marker({
        position: marker.position,
        map: this.map,
        title: marker.title
    });
    }
}

感谢任何帮助!

非常感谢

埃内斯托

你能检查一下(通过添加 console.log)是否在打开模式时触发了它:

ngOnInit() {
    this.LocationService.loadMap("page3");

    } 

您可以使用 elementRef 并像这样传递它:

将服务更改为:

loadMap(prmtrMapId, elRef: ElementRef) {
   const mapEle: HTMLElement = elRef.nativeElement;
}

在第 3 页中将 html 更改为

<ion-content>
    <div #map></div>
    <ion-button href = "home" expand = "block" >home</ion-button>
</ion-content>

然后在 ts 中添加 ViewChild 并像这样调用服务

@ViewChild('map') mapEl: ElementRef;

ngAfterViewInit(){
   this.LocationService.loadMap("page3", this.mapEl);
}

因为“视图查询是在调用 ngAfterViewInit 回调之前设置的。”您需要使用 ngAfterViewInit 或 static: true.

https://angular.io/api/core/ViewChild#description