Открыть всплывающее окно при клике за пределами карты - PullRequest
1 голос
/ 17 июня 2019

У меня есть список, и, нажав на элемент списка, я хочу открыть всплывающее окно на маркере.В настоящее время всплывающее окно открывается только при нажатии на маркер.

Так я создаю маркер и всплывающие окна

import React from 'react';
import {
  CircleMarker,
  Popup,
} from 'react-leaflet';

class PointsLayer extends React.Component {
  render() {
    const { data } = this.props;
    return (
      data.map(point => {
        return (
          <CircleMarker
            key={point.id}
            center={point.coordinates}>
            <Popup>
              Fancy Pop Up
            </Popup>
          </CircleMarker>
        )
      })
    )
  }

и

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  Map,
} from 'react-leaflet';
import L from 'leaflet';
import PointsList from './PointsList;
import PointsLayer from './PointsLayer;

class Map extends React.Component {

componentDidMount() {
    this.map = this.mapInstance.leafletElement;
}

render() {
  const { data } = this.props;
  return (
    <>
      <Map
        ref={e => { this.mapInstance = e }}}>
        <TileLayer
          url=..." />
        <PointsLayer
           data={data} />
       </Map>
       <PointsList
         data={data} />
     </>
   )
 }

}

Каждая точка данных от data - это маркер от <Map /> до <PointsLayer /> компонента и список в <PointsList />.Я хочу открыть всплывающее окно в <PointsLayer /> при нажатии на соответствующую запись в <PointsList />.

Как мне это сделать?

Ответы [ 2 ]

1 голос
/ 13 июля 2019

Для открытия Popup Marker.openPopup() можно использовать метод .Следующий компонент демонстрирует, как получить доступ к собственному объекту Marker в библиотеке react-leaflet и открыть всплывающее окно:

function MarkerExample(props) {
  const markerRef = useRef(null);
  const { center, content, openPopup } = props;

  useEffect(() => {
    markerRef.current.leafletElement.openPopup();
  }, []);

  return (
    <CircleMarker ref={markerRef} center={center}>
      <Popup>{content}</Popup>
    </CircleMarker>
  );
}

Вот список изменений для вашего примера:

a) представить отдельный компонентдля маркера, который принимает openPopup реквизит, чтобы определить, нужно ли открывать всплывающее окно:

function PointMarker(props) {
  const markerRef = useRef(null);
  const { center, content, openPopup } = props;

  useEffect(() => {
    if (openPopup) markerRef.current.leafletElement.openPopup();
  }, [openPopup]);

  return (
    <CircleMarker ref={markerRef} center={center}>
      <Popup>{content}</Popup>
    </CircleMarker>
  );
}

b) изменить PointsList компонент для передачи индекс выбранного элемента через обработчик событий, например:

function PointsList(props) {
  const { data, onItemClick } = props;
  return (
    <div>
      <ul>
        {data.map((item, index) => (
          <li
            key={index}
            onClick={e => {
              onItemClick(index);
            }}
          >
            {item.name}
          </li>
        ))}
      </ul>
    </div>
  );
}

c) И, наконец, в компонент карты введите индекс выбранного маркера как переменную состояния .Теперь при нажатии на внешний элемент обновите выбранный индекс, чтобы открыть всплывающее окно:

function MapExample(props) {
  const [selected, setSelected] = useState();
  const { zoom, center, locations } = props;

  function handleItemClick(index) {
    setSelected(index);
  }

  return (
    <div>
      <PointsList data={locations} onItemClick={handleItemClick} />
      <Map center={center} zoom={zoom}>
        <TileLayer url="https://{s}.tile.osm.org/{z}/{x}/{y}.png" />
        <PointsLayer selectedIndex={selected} data={locations}  />
      </Map>
    </div>
  );
}

Вот демоверсия

0 голосов
/ 19 июня 2019

Вы можете использовать прослушиватель onClick для объекта (списка), чтобы при нажатии на элементы списка вызывалось что-то вроде этой функции.

onItemClick: function (event) {
// open popup method 
    event.openPopup();

},
...