单击列表项时如何打开相应的标记信息窗口

时间:2018-08-12 11:15:50

标签: javascript reactjs google-maps buttonclick

我有一个要绑定到地图标记的位置项列表(如<li>元素),因此,当单击<li>元素时,它将打开相应的信息窗口。这是代码:

/* This import the static locations .js file for the default markers */
import { StaticLocations } from "./StaticLocations";

let map;
let markers = [];

class App extends Component {
state = {
  locations: StaticLocations,
  map: {},
  filterQuery: "",
  mapInitialization: true,
  infowindowOpen: false,
  venuesList: [],
  foundVenues: [],
  hamburgerToggled: false,  // Set initial hamburger menu state
};

此函数初始化地图和地图对象。

initMap() {
const initialCenter = new window.google.maps.LatLng( 45.438384, 10.991622 );
let mapOptions = {
  zoom: 14,
  center:  initialCenter,
  styles: MapStyles,
  mapTypeId: window.google.maps.MapTypeId.ROADMAP
};

/* Create map */
map = new window.google.maps.Map(document.getElementById( "map" ), mapOptions);

/* Create infowindow */
const largeInfoWindow = new window.google.maps.InfoWindow({
  maxWidth: 350
});

/* Loop through the locations array and create a marker for each coordinates */
for ( let i = 0; i < locations.length; i++ ) {
  const position = locations[i].locationCoords;
  const locationTitle = locations[i].locationName;

  const newMarker = new window.google.maps.Marker({
    map: map,
    position: position,
    title: locationTitle,
    animation: window.google.maps.Animation.DROP,
    icon: markerIcon,
    id: i
  });

  /* Push the newly created markers to the markers array */
  markers.push( newMarker );

  /* Listen for a click event to open the corresponding infowindow */
  newMarker.addListener("click", () => {
    this.populateInfoWindow( newMarker, largeInfoWindow );
  });

  /* Close infowindow when the map is clicked on */
  this.onMapClicked ( largeInfoWindow );

  /* Extend the map boundaries to include the markers */
  bounds.extend( markers[i].position );
}   
// Extend the boundaries of the map for each marker
map.fitBounds (bounds );
}

/* Create infowindow content and link it to the corresponding marker */
populateInfoWindow( marker, infowindow ) {
let infoWindowContent = `<div id="info-window">
                            <h3>${marker.title}</h3>
                            <p>Description here</p>
                         </div>`;
if ( infowindow.marker !== marker ) {
  infowindow.marker = marker;
  infowindow.setContent( infoWindowContent );
  infowindow.open( map, marker );
  }
}

render() {

/* Destructure state variables for readability */
const { hamburgerToggled, foundVenues, locations } = this.state;

return (

  <div id="app-container" role="main">

    {/* Display an error message if there was a probolem with the API call */}
    <div id="display-error-field"></div>

     {/* Header component */}
     <Header />

      <main className="main-map">

      {/* Side menu */} 
      <aside className = { hamburgerToggled ? "hamburger-show" : "hamburger-hide" }>

        <div id="list-wrapper">

          {/* Input component */}
          <FilterLocations 
          />

下面是我要链接到标记的位置列表:当我单击位置列表项时,地图应聚焦于相应的标记并打开信息窗口。

          <ul id="list-aside">
            { locations.map(( location, index ) => {
              return (
              <li 
                key = { index }
                onClick = { () => alert( "clicked on " + location.locationName ) }
                >{ location.locationName }</li>
              );
            })};
          </ul>
        </div>
      </aside>

    {/* Map component */}
    <section className="map-container">
      <Map />

    </section>
   </main>
  </div>
 );
}

P.s .:这是StaticLocations文件,该文件的坐标已获取以显示默认标记:

export const StaticLocations = [{
locationCoords: {
  lat: 45.42422,
  lng: 10.991686
},
locationName: "Mizuki Lounge Restaurant",
locationId: "5952389dccad6b171c8d3e58",
address: "",
},
{
locationCoords: {
  lat: 45.448458542692556,
  lng: 11.00220835305019
},
locationName: "TeodoricoRe Restaurant Bar Verona",
locationId: "4dcee64f45ddbe15f8956f72",
address: ""
},
{
locationCoords: {
  lat: 45.438385,
  lng: 10.991622
},
locationName: "Hotel Montemezzi Restaurant",
locationId: "59c1f834a2a6ce4762f1de1e",
address: ""
},
{
locationCoords: {
  lat: 45.44499306798319,
  lng: 10.998014420366752
},
locationName: "AMO Opera Restaurant",
locationId: "52630778498ef9cb50326fb7",
address: ""
},
{
locationCoords: {
  lat: 45.44232305284876,
  lng: 10.99606990814209
},
locationName: "Sun Restaurant",
locationId: "5590d1da498e4edbe573034b",
address: ""
}
];

我希望我能弄清楚我的问题。如果不是,并且如果您认为可以改善此问题,请拒绝投票,但请,我的意思是,请提供建设性的意见:这是一个学习平台,我想忍受,学习甚至从我自己的错误。谢谢:)

1 个答案:

答案 0 :(得分:1)

关于

  

当我单击位置列表项时,地图应集中在   相应的标记,然后打开信息窗口。

您可以考虑以下更改列表:

a)引入selectedItem以组件状态存储所选列表项,并在单击li后对其进行更新:

  state = {
    selectedItem: null
  }

  showInfo(e, id) {
    let result = data.find(item => {
      return item.locationId === id;
    });
    this.setState({ "selectedItem": result });
  }

b)将selectedItem值作为 prop 传递给Map组件以显示信息窗口:

render() {
    return (
      <div>
        <ul>
          {data.map((item, index) => {
            return <li key={index} onClick={e => this.showInfo(e, item.locationId)}>{item.locationName}</li>;
          })}
        </ul>

          <Map center={{ lat: 45.438384, lng: 10.991622 }} zoom={14} data={data} selectedItem={this.state.selectedItem} />
      </div>
    );
  }
Map组件中的

c)为每个选定的项目找到相应的标记并显示信息窗口:

componentDidUpdate() {
    if (this.props.selectedItem) {
        //1. find selecter marker object
        let selectedMarker = this.markers.find(m => {
            return m.id === this.props.selectedItem.locationId;
        });
        //2.show info window goes here...
    }
}

Demo