在Ionic中使用ElementRef将地图加载到ngSwitch子作用域 [英] Loading map to ngSwitch child scope using ElementRef in Ionic

查看:519
本文介绍了在Ionic中使用ElementRef将地图加载到ngSwitch子作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 @ViewChild ElementRef 访问ngSwitchCase视图,以在我的Ionic 3应用中加载谷歌地图。我了解ngSwitch创建了自己的作用域,但无法访问,因此我可以将地图从Google加载到 #map id =mapdiv mapView ngSwitchCase



page.ts

  //导入
从'@ angular / core'导入{ElementRef,ViewChild};

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

//导出类中的属性
@ViewChild('map')mapElement:ElementRef;
views:string =listView;

构造函数(public navCtrl:NavController){}

//函数
ionViewDidLoad(){
this.loadMap();
}

loadMap(){
this.geolocation.getCurrentPosition()。then((position)=> {
let latLng = new google.maps。 LatLng(position.coords.latitude,position.coords.longitude);
//初始化地图属性
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>
列出
< / 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'>
//其他东西
< / ion-list>
< / div>
< / ion-content>


解决方案

ngSwitch动态创建并销毁各个DOM元素。由于您开始使用

  views:string =listView; 

离子列表

 < ion-list * ngSwitchCase ='mapView'> 

在DOM中不存在。因此,作为离子列表的孩子的地图div不存在。因此 mapElement:ElementRef 为空。如果你使用像

  views:string =mapView; 

您的代码可能会运行并创建一次地图。去尝试一下。这个对我有用。 注意在切换细分受众群时,地图已被销毁,并且可能不会再次创建,因为您的 loadMap()只运行一次。



此时,您有两种选择。


  1. 取代ngSwitch /销毁元素),使用show / hide Map和List。

      .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>
    //其他东西
    < / ion-list>
    < / div>
    < / ion-content>


  2. 使用带有Map选项卡和List选项卡的选项卡组件。 b
    $ b

    page.ts

      import {ElementRef,ViewChild}从'@ angular / core'; 
    从'../list/list'导入{ListPage};
    从'../map/map'导入{MapPage};

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

    views:string =listView;

    tab1Root = MapPage;
    tab2Root = ListPage;

    构造函数(public navCtrl:NavController){}

    }

    page.html

     < ion-content> 
    < ion-tabs>
    < ion-tab [root] =tab1RoottabTitle =MaptabIcon =map>< / ion-tab>
    < ion-tab [root] =tab2RoottabTitle =ListtabIcon =list>< / ion-tab>
    < / ion-tabs>
    < / ion-content>

    map.ts

     

    导出类MapPage {

    @ViewChild('map')mapElement:ElementRef;
    $ b构造函数(){}

    ionViewDidLoad(){
    this.loadMap();


    loadMap(){
    // stuff here
    }
    }


  3. 另外,我注意到您正在创建一个包含

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

    你不想只有一张地图吗?不应该像

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



    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>
    

    解决方案

    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'">
        .
        .
    

    这篇关于在Ionic中使用ElementRef将地图加载到ngSwitch子作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆