【问题标题】:When displaying multiple markers on a map, how to open just one info window, when clicking on a marker?在地图上显示多个标记时,单击标记时如何只打开一个信息窗口?
【发布时间】:2023-03-13 08:52:01
【问题描述】:

我正在使用react-google-maps 显示带有标记的地图,当您单击标记时,所有信息窗口都会打开。当我点击它时,我想只显示一个标记的信息窗口,而其他的则保持关闭。

这是我的代码:

    <GoogleMap
        defaultZoom={15}
        defaultCenter={{ lat: 51.508530, lng: -0.076132 }}
    >
        {props.places && props.places.map((place, i) =>
            <Marker onClick={props.onToggleOpen} key={i} position={{ lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }} >
                {props.isOpen && <InfoWindow onCloseClick={props.onToggleOpen}>
                  <div>{place.name}</div>
                </InfoWindow>}
            </Marker>
        )}
    </GoogleMap>

我用这个打开和关闭信息窗口

import { compose, withProps, withStateHandlers, withHandlers, withState } from "recompose";

...

withStateHandlers(() => ({
  isOpen: false,
}), {
  onToggleOpen: ({ isOpen, id }) => () => ({
    isOpen: !isOpen,
  })
}),

我正在绘制所有标记,并将它们显示在地图上。我怎么能点击打开一个标记信息窗口? Here is a related question,但它不是用 React 制作的,也不使用 react-google-maps。

【问题讨论】:

    标签: javascript reactjs google-maps google-maps-api-3 react-google-maps


    【解决方案1】:

    这更像是一个React 问题。您可以将点击的Marker 的索引传递给onToggleOpen,而不是isOpen,您可以使用selectedPlace 状态来保存点击的Marker 的索引,并使用该索引来呈现正确的InfoWindow

    这是一个示例(未完全测试,但您可以理解):

    /*global google*/
    import React from "react"
    import { compose, withProps, withHandlers, withState, withStateHandlers } from "recompose"
    import { withScriptjs, withGoogleMap, GoogleMap, Marker, InfoWindow } from "react-google-maps"
    
    const MyMapComponent = compose(
        withProps({
            googleMapURL: "https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places",
            loadingElement: <div style={{ height: `100%` }} />,
            containerElement: <div style={{ height: `400px` }} />,
            mapElement: <div style={{ height: `100%` }} />,
        }),
        withScriptjs,
        withGoogleMap,
        withState('places', 'updatePlaces', ''),
        withState('selectedPlace', 'updateSelectedPlace', null),
        withHandlers(() => {
            const refs = {
                map: undefined,
            }
    
            return {
                onMapMounted: () => ref => {
                    refs.map = ref
                },
                fetchPlaces: ({ updatePlaces }) => {
                    let places;
                    const bounds = refs.map.getBounds();
                    const service = new google.maps.places.PlacesService(refs.map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED);
                    const request = {
                        bounds: bounds,
                        type: ['hotel']
                    };
                    service.nearbySearch(request, (results, status) => {
                        if (status == google.maps.places.PlacesServiceStatus.OK) {
                            console.log(results);
                            updatePlaces(results);
                        }
                    })
                },
                onToggleOpen: ({ updateSelectedPlace }) => key => {
                    updateSelectedPlace(key);
                }
            }
        }),
    )((props) => {
        console.log(props);
        return (
            <GoogleMap
                onTilesLoaded={props.fetchPlaces}
                ref={props.onMapMounted}
                onBoundsChanged={props.fetchPlaces}
                defaultZoom={15}
                defaultCenter={{ lat: 51.508530, lng: -0.076132 }}
            >
                {props.places && props.places.map((place, i) =>
                    <Marker onClick={() => props.onToggleOpen(i)} key={i} position={{ lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }}>
                        {props.selectedPlace === i && <InfoWindow onCloseClick={props.onToggleOpen}>
                            <div>
                                {props.places[props.selectedPlace].name}
                            </div>
                        </InfoWindow>}
                    </Marker>
                )}
            </GoogleMap>
        )
    })
    
    export default class MyFancyComponent extends React.PureComponent {
        render() {
            return (
                <MyMapComponent />
            )
        }
    }
    

    【讨论】:

    • 如何切换信息窗口是否打开的真/假状态?
    • 您使用selectedPlace 来控制它。基本上,如果它是 null,则没有打开 InfoWindow,如果它不为 null,则意味着打开了 infoWindow,您应该填充有关索引等于 selectedPlace 的位置的信息。跨度>
    • 在加载地图时出现大量控制台错误。例如 withHandlers 的问题。我想知道为什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多