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

问题描述

我正在尝试使用 @ViewChildElementRef 访问 ngSwitchCase 视图,以在我的 Ionic 3 应用程序中加载谷歌地图.我知道 ngSwitch 创建了自己的范围,但无论如何都无法访问它,因此我可以将地图从 google 加载到 #map id="map" divem>mapView ngSwitchCase?

page.ts

//导入从@angular/core"导入 { ElementRef, ViewChild };@成分({选择器:'页面浏览量',templateUrl: 'views.html'})导出类 ViewsPage {//导出类中的属性@ViewChild('map') mapElement : ElementRef;意见:字符串=列表视图";构造函数(公共导航控件:导航控制器){}//函数ionViewDidLoad(){this.loadMap();}加载映射(){this.geolocation.getCurrentPosition().then((position) => {让 latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);//初始化地图属性让地图选项 = {中心:纬度,变焦:15,mapTypeId: google.maps.MapTypeId.ROADMAP};this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);});}}

page.html

<ion-segment [(ngModel)]="views"><ion-segment-button value="mapView">地图</ion-segment-button><ion-segment-button value="listView">列表</ion-segment-button></离子段></ion-toolbar><离子含量填充><div [ngSwitch]="视图"><ion-list *ngSwitchCase="'mapView'"><离子项目><div #map id="地图"></div></ion-item></ion-list><ion-list *ngSwitchCase="'listView'">//其他的东西</ion-list>

</离子含量>

解决方案

ngSwitch 动态地创建和销毁相应的 DOM 元素.由于您开始使用

初始化为列表视图的默认视图

views: string = "listView";

离子列表是

在 DOM 中不存在.因此,作为 ion-list 的孩子的带有 map 的 div 不存在.因此 mapElement : ElementRef 为空.有可能,如果您从带有地图的默认段视图开始,例如

views: string = "mapView";

您的代码可能会运行一次并创建地图.就试一试吧.这个对我有用.注意,在切换段时,地图会被破坏并且可能无法再次创建,因为您的 loadMap() 只运行一次.

此时,您有两个选择.

  1. 使用显示/隐藏 Map 和 List 代替 ngSwitch(创建/销毁元素).

    page.scss

     .hide{显示:无!重要;}

    page.html

    <div #map id="map" [ngClass]="{ 'hide': views != 'mapView' }"></div><div [ngClass]="{ 'hide': views != 'listView' }"><离子列表>//其他的东西</ion-list>

</离子含量>

  • 有一个带有地图选项卡和列表选项卡的选项卡组件.

    page.ts

    import { ElementRef, ViewChild } from '@angular/core';从 '../list/list' 导入 { ListPage };从 '../map/map' 导入 { MapPage };@成分({选择器:'页面浏览量',templateUrl: 'views.html'})导出类 ViewsPage {意见:字符串=列表视图";tab1Root = MapPage;tab2Root = ListPage;构造函数(公共导航控件:导航控制器){}}

    page.html

     <离子标签><ion-tab [root]="tab1Root" tabTitle="Map" tabIcon="map"></ion-tab><ion-tab [root]="tab2Root" tabTitle="List" tabIcon="list"></ion-tab></ion-tabs></离子含量>

    ma​​p.ts

    ..导出类 MapPage {@ViewChild('map') mapElement : ElementRef;构造函数(){}ionViewDidLoad(){this.loadMap();}加载映射(){//这里的东西}}

  • 此外,我注意到您正在使用

    创建地图列表

    <离子项目><div #map id="地图"></div></ion-item></ion-list>

    你不想要一张地图吗?这不应该是这样的

     

    <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 子作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-05 17:56