Loading map into ngSwitch extension area using ElementRef in Ionic

I am trying to access the ngSwitchCase view using @ViewChild and ElementRef to load the google map in my Ionic 3 app. I understand that ngSwitch creates its own scope, but it is not available anyway, so I can load the map from google in # map id = "map" div in 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>

      

+3


source to share


1 answer


ngSwitch creates and destroys the corresponding DOM element dynamically. Since you are starting the default view, initialized to view the list with

views: string = "listView";

      

an ionic list that

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

      

does not exist in the DOM. Hence the div with the display being a child of the ionic list does not exist. Hence mapElement : ElementRef

it is null. Perhaps if you start by displaying a default segment with a map like

views: string = "mapView";

      

your code can run and create a map in one go. Just try it. I like. Note that when switching segments, the map is destroyed and may not be created again, since yours loadMap()

only works once.



At this point, you have two options.

  • Instead of ngSwitch (which creates / destroys items), 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>
    
          

  • You have a tab 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 cards with

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

      

Don't you just need one card? Shouldn't it be

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

      

+2


source







All Articles