Loading map to ngSwitch child scope using ElementRef in Ionic

对着背影说爱祢 提交于 2019-12-23 17:09:41

问题


I'm trying to access a ngSwitchCase view using @ViewChild and ElementRef to load a google map in my Ionic 3 app. I understand the ngSwitch creates its own scope but is it not accessible in anyway so I can load the map from google to the #map id="map" div in the mapView ngSwitchCase?

page.ts

//the import
import { ElementRef, ViewChild } from '@angular/core';

@Component({
  selector: 'page-views',
  templateUrl: 'views.html'
})
export class ViewsPage {

//the attribute in the export class
@ViewChild('map') mapElement : ElementRef;
views: string = "listView";

  constructor(public navCtrl: NavController) {}

  //the functions 
  ionViewDidLoad(){
    this.loadMap();
  }

  loadMap(){
    this.geolocation.getCurrentPosition().then((position) => {
      let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
      // initializing map attributes
      let mapOptions = {
        center: latLng,
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };
      this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
    });
  }
}

page.html

<ion-toolbar>
  <ion-segment [(ngModel)]="views">
    <ion-segment-button value="mapView">
      Map
    </ion-segment-button>
    <ion-segment-button value="listView">
      List
    </ion-segment-button>
  </ion-segment>
</ion-toolbar>

<ion-content padding>
  <div [ngSwitch]="views">
    <ion-list *ngSwitchCase="'mapView'">
      <ion-item>
        <div #map id="map"></div>
      </ion-item>
    </ion-list>

    <ion-list *ngSwitchCase="'listView'">
      //other stuff
    </ion-list> 
  </div> 
</ion-content>

回答1:


ngSwitch creates and destroys the respective DOM element dynamically. Since you start your default view initialized to list view with

views: string = "listView";

the ion-list which is

<ion-list *ngSwitchCase="'mapView'">

does not exist in DOM. Consequently, the div with map, which is child of ion-list does not exist. Hence mapElement : ElementRef is null. Its possible that if you start with default segment view with map like

views: string = "mapView";

your code might run and create the map for once. Just try it. It works for me. Note that on switching segments the map is destroyed and may not be created again since your loadMap() only runs one time.

At this point, you have two options.

  1. Instead of ngSwitch (which creates/destroys elements), use show/hide Map and List.

    page.scss

     .hide 
     {
      display: none !important;
     }
    

    page.html

    <ion-content padding>
        <div #map id="map" [ngClass]="{ 'hide': views != 'mapView' }"></div>
        <div [ngClass]="{ 'hide': views != 'listView' }">
            <ion-list >
             //other stuff
            </ion-list> 
        </div> 
    </ion-content>
    
  2. Have a tabs component with a Map tab and a List tab.

    page.ts

    import { ElementRef, ViewChild } from '@angular/core';
    import { ListPage } from '../list/list';
    import { MapPage } from '../map/map';
    
    @Component({
      selector: 'page-views',
      templateUrl: 'views.html'
    })
    export class ViewsPage {
    
       views: string = "listView";
    
       tab1Root = MapPage;
       tab2Root = ListPage;
    
       constructor(public navCtrl: NavController) {}
    
    }
    

    page.html

      <ion-content>
        <ion-tabs>
         <ion-tab [root]="tab1Root" tabTitle="Map" tabIcon="map"></ion-tab>
         <ion-tab [root]="tab2Root" tabTitle="List" tabIcon="list"></ion-tab>
        </ion-tabs>
      </ion-content>
    

    map.ts

    .
    .
    export class MapPage { 
    
      @ViewChild('map') mapElement : ElementRef;
    
      constructor(){}
    
      ionViewDidLoad(){
        this.loadMap();
      }
    
      loadMap(){
        //stuff here
      }
     }
    

Also, I noticed that you are creating a list of maps with

<ion-list *ngSwitchCase="'mapView'">
  <ion-item>
     <div #map id="map"></div>
  </ion-item>
</ion-list>

Don't you want just one map? Shouldn't this be like

 <div [ngSwitch]="views">
    <div #map id="map" *ngSwitchCase="'mapView'"></div>
    <ion-list *ngSwitchCase="'listView'">
    .
    .


来源:https://stackoverflow.com/questions/43745022/loading-map-to-ngswitch-child-scope-using-elementref-in-ionic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!