代码之家  ›  专栏  ›  技术社区  ›  Bruno Mazza

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

  •  0
  • Bruno Mazza  · 技术社区  · 6 年前

    我有一个位置项目列表(如 <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.:以下是静态位置文件,其坐标是为显示默认标记而提取的:

    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 回复  |  直到 6 年前
        1
  •  1
  •   Vadim Gremyachev    6 年前

    关于

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

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

    a)介绍 selectedItem 以组件状态存储选定的列表项并更新一次 li 单击:

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

    b)通过 选择项 值为 支柱 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>
        );
      }
    

    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