在地图外单击打开弹出窗口
Open Pop Up on Click Outside of Map
我有一个列表,通过单击列表元素,我想打开标记上的弹出窗口。目前,弹出窗口仅在单击标记时打开。
这就是我创建标记和弹出窗口的方式
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 />
中的一个侦听器。
单击 <PointsList />
中的相应条目时,我想在 <PointsLayer />
中打开弹出窗口。
我该怎么做?
您可以在对象(列表)上使用 onClick 侦听器,以便在单击列表元素时调用类似此函数的功能。
onItemClick: function (event) {
// open popup method
event.openPopup();
},
打开PopupMarker.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
属性来确定是否需要打开 Popup:
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>
);
}
我有一个列表,通过单击列表元素,我想打开标记上的弹出窗口。目前,弹出窗口仅在单击标记时打开。
这就是我创建标记和弹出窗口的方式
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 />
中的一个侦听器。
单击 <PointsList />
中的相应条目时,我想在 <PointsLayer />
中打开弹出窗口。
我该怎么做?
您可以在对象(列表)上使用 onClick 侦听器,以便在单击列表元素时调用类似此函数的功能。
onItemClick: function (event) {
// open popup method
event.openPopup();
},
打开PopupMarker.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
属性来确定是否需要打开 Popup:
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>
);
}