在地图外部点击打开弹出窗口

时间:2019-06-17 14:20:35

标签: javascript reactjs leaflet react-leaflet

我有一个列表,然后通过单击元素列表来打开标记上的弹出窗口。当前,仅在单击标记时弹出窗口会打开。

这就是我创建标记和弹出窗口的方式

$checkifuserExist= DB::table('track_dailies')->where('user_id','=',\Auth::user())->where('created_at','>=',Carbon::today())->count();
if($checkifuserExist>0)
{
   //if user really exists
     if( $hasUserEntries = DB::table('track_dailies')->where('user_id','=',\Auth::user())->where('created_at','>=',Carbon::today())->first())
       {
             //update the value of the amount
       }
      else{

           //insert new record

         }

}
else
{

  // if the user does not exist, do something else...
}

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 />中的弹出窗口。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

可以使用打开弹出窗口Marker.openPopup() method。以下组件演示了如何访问react-leaflet库中的本机Marker对象并打开Popup:

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),最后在地图组件中,将所选标记的索引引入state variable。现在,单击外部元素后,更新所选索引以打开弹出窗口:

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>
  );
}

Here is a demo

答案 1 :(得分:-1)

您可以在对象(列表)上使用onClick侦听器,以便在单击列表元素时调用类似此功能的东西。

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

},