1

当我在组件中使用组件时,我有一个案例。通过@ViewChild 访问子组件的属性,我得到子组件中的方法的未定义。

// Parent component

declare var google: any;
@Component({
  selector: 'app-map',
  templateUrl: `
    <div id="map"></div>
    <app-context-menu></app-context-menu>`,
  styleUrls: ['./map.component.css'],
  providers: [CitiesService],
})

export class MapComponent implements AfterViewInit {
  @ViewChild(ContextMenuComponent) contextMenu: ContextMenuComponent;
  user: UserInterface;
  city: any;
  map: any;

  constructor(
    private userStorage: UserStorage, 
    private citiesService: CitiesService,
    private theMap: TheMap,
  ) {}

  ngAfterViewInit() {
    this.findUserCityCoords();
  }

  inittializeMap(mapOpts) {

    let mapProps = {
      center: new google.maps.LatLng(mapOpts.lat, mapOpts.lng),
      zoom: mapOpts.zoom,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    let map = new google.maps.Map(document.getElementById('map'), mapProps);
    let menu = this.contextMenu;

    map.addListener('rightclick', (e) => {
      console.log('map', this);
      console.log('menu', this.contextMenu);
      this.contextMenu.open(e);
    });
  }

  findUserCityCoords() {
    let userCity = this.userStorage.getFromStorage().city;

    this.citiesService.getCityConfig()
      .subscribe(cities => {
        cities.forEach(city => {
          if (city.name === userCity) this.inittializeMap(city.center);
        });
      });
  }

当'map event listener'调用'menu.open(e);'时从这个类 上下文发生变化,在子组件内部,子组件的方法不可用。调用即'this.draw()' 方法。

// Child component
import { Component, OnInit, ElementRef, AfterViewInit } from 

'@angular/core';
import { TheMap } from '../../services/mapServices/TheMap';
import { Marker } from '../../services/mapServices/marker.service';
declare var google: any;

@Component({
  selector: 'app-context-menu',
  templateUrl: './context-menu.component.html',
  styleUrls: ['./context-menu.component.css']
})
export class ContextMenuComponent {
  overlay;
  el;

  constructor(
    private theMap: TheMap, 
    private marker: Marker,
    private elementRef: ElementRef
  ) {
    this.overlay = new google.maps.OverlayView();
  }

  ngAfterViewInit() {}

  open(e) {
    let map = this.theMap.getMap();
    this.overlay.set('position', e.latLng);
    this.overlay.setMap(map);
    this.draw(); // <---- Here, this.draw() is not a function
    // So I can access properties from constructor but not this.draw() and other methods of this class
  };

  draw() {
    // ....
  }

如何正确实现 google 的 map 'rightclick' 事件监听器(可能带有 'bind')来使用我孩子的组件方法。谢谢

4

1 回答 1

1

不确定我是否理解这个问题,但() =>(箭头功能)可能是您正在寻找的

map.addListener('rightclick', (e) => {
  console.log('map', this);
  console.log('menu', menu);
  this.contextMenu.open(e);
});
于 2016-11-24T13:05:43.210 回答