在地图上显示多个标记时,单击标记时如何只打开一个信息窗口?

Posted

技术标签:

【中文标题】在地图上显示多个标记时,单击标记时如何只打开一个信息窗口?【英文标题】:When displaying multiple markers on a map, how to open just one info window, when clicking on a marker? 【发布时间】:2018-04-22 15:25:49 【问题描述】:

我正在使用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。

【问题讨论】:

【参考方案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 的问题。我想知道为什么?

以上是关于在地图上显示多个标记时,单击标记时如何只打开一个信息窗口?的主要内容,如果未能解决你的问题,请参考以下文章

单击标记时,新按钮会自动出现在谷歌地图(Android)上?如何删除?

如何突出显示在我的传单地图(nuxt/vue)中单击了哪个标记

如何在谷歌地图android上设置多个标记?

为啥要在标记点击事件上重新渲染地图?

如何保存多个谷歌地图标记,它们在 Firebase 实时数据库中的位置,并在打开应用程序时再次显示它们

单击标记时打开不同的活动(多个标记)