在DOM对象存在后初始化Angular2组件中的leaflet地图

3

我目前正在尝试在angular material2 tab-group中创建一个leaflet地图,如下所示:

import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { MaterialModule } from '@angular/material';

import { Component, OnInit, OnDestroy } from '@angular/core';
import 'leaflet';

@Component({
  selector: 'minimap',
  template: `<div #minimap [id]="id" class=leaflet-map></div>`
})
export class MiniMap implements OnInit, OnDestroy {
  map: L.Map = null;
  id: string;

  constructor() { 
    this.id = "map" + Date.now();
  }

  ngOnInit() {
    this.map = L.map(this.id).setView([54.5, -115.0], 13);
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      maxZoom: 18,
      attribution:
      '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(this.map);
  }

  ngOnDestroy() { }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <md-tab-group>
      <md-tab label="tab 1">
      tab 1 content
      </md-tab>
      <md-tab label="tab 2">
      tab 2 content
      </md-tab>
      <md-tab label="map tab">
      <minimap></minimap>
      </md-tab>
      </md-tab-group>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

很遗憾,在组件中尝试创建地图时,会出现一个错误,提示地图容器尚不存在。我的解释是代码当前在DOM对象创建之前运行。
正确的创建地图的方法是什么,以便在DOM对象存在时调用代码?请参照以下链接:https://plnkr.co/edit/dLwhv3XoMWMYFkqztkuR?p=preview。请确保按照格式要求进行操作。

如果您尝试在 ngAfterViewInit() 中执行此操作会发生什么? - developer033
抱歉,我忘了提到,我在将地图初始化放置在“AfterContentInit”和“AfterViewInit”中时看到了相同的行为。 - Bjorn Harpe
2个回答

6

看起来直接通过@ViewChild引用地图容器元素是没有问题的。

import {Component, ViewChild} from '@angular/core';
import 'leaflet';

@Component({
    selector: 'minimap',
    template: `<div #mapDiv></div>`
})
export class MiniMap implements OnInit {
    @ViewChild('mapDiv') mapContainer;

    ngOnInit() {
        this.map = L.map(this.mapContainer.nativeElement);
    }
}

更新的Plunk: https://plnkr.co/edit/HGWb3J1f5HL8shFW9EUN?p=preview 然而,当选项卡首次显示时,似乎需要重新初始化地图大小(至少第一次)。请参见Data-toggle tab does not download Leaflet map

1
这肯定是有效的,但我不太理解它,Leaflet无法通过ID在DOM中找到元素,但它仍然存在,我们可以使用viewChild访问它??难道只是组件DOM尚未插入页面,因此leaflet找不到它吗? - Bjorn Harpe
2
@BjornHarpe:我也是这么猜的。Leaflet试图在document查找元素 - ghybs

1

我忘了提到我已经尝试过AfterViewInitAfterContentInit,并观察到相同的行为,是否还有其他点我应该尝试挂钩? - Bjorn Harpe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接