(React)在Google Maps Marker上打开模态单击

时间:2016-10-17 01:13:45

标签: javascript google-maps reactjs ecmascript-6

更新:添加了Dandy我现在可以访问componentDidMount中的this.setState函数,如果我将它绑定到componentDidMount,但是因为this.setState在componentDidMount中,this.setState不是函数。

我想我必须在componentDidMount之外构建地图,但我不知道从哪里开始

原件:

所以我在React中构建一个Google Map,我想在标记点击上打开一个模态。

我的渲染中有模态和

marker.addListener('click', function() {
          infowindow.open(map, marker);
          this.setState({ showModal: true });
        });

在componentDidMount中,但我看到我无法改变componentDidMount中的状态...有关如何让我的模态显示在标记点击上的任何建议吗?

import React from 'react';
import {Link} from 'react-router';
import {
    Row,
    Col,
    FormGroup,
    ControlLabel,
    FormControl,
    Button,
    Grid,
    Modal,
    Popover,
    Tooltip,
    OverlayTrigger
} from 'react-bootstrap';

export class Maps extends React.Component {
    constructor(props) {
        super(props);
            userPosition: {lat: 40.7128, lng: -74.0059},
            defaultCenter: {
                lat: 40.7128,
                lng: -74.0059
            },
            showModal: false,
        };
        this.close = this.close.bind(this);
        this.open = this.open.bind(this);
        this.componentDidMount = this.componentDidMount.bind(this);
    }

    close() {
        this.setState({ showModal: false });
      }

    open() {
        this.setState({ showModal: true });
      }
  
    componentDidMount() {
        // this.getCurrentPosition();
        var contentString = '<div id="content">'+
            '<div id="siteNotice">'+
            '</div>'+
            '<h1 id="firstHeading" class="firstHeading">New York</h1>'+
            '<div id="bodyContent">'+
            '<p>content string</p>'+
            '</div>'+
            '</div>';

        let sourland = {lat: 40.473927, lng: -74.694482};

        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 12,
            center: {
                lat: 40.7128,
                lng: -74.0059
            }
        });

        var infowindow = new google.maps.InfoWindow({
          content: contentString,
          maxWidth: 200
        });

        var marker = new google.maps.Marker({
          position: sourland,
          map: map,
          title: 'Uluru (Ayers Rock)'
        });

        // modal code
        marker.addListener('click', function() {
          infowindow.open(map, marker);
          this.setState({ showModal: true });
        });
    }


    render(){
        console.log(this.state);

        const popover = (
          <Popover id="modal-popover" title="popover">
            very popover. such engagement
          </Popover>
        );
        const tooltip = (
          <Tooltip id="modal-tooltip">
            wow.
          </Tooltip>
        );

        return (
            <div>
                <div id="map" className="map-container"></div>

                <Button
                  bsStyle="primary"
                  bsSize="large"
                  onClick={this.open}
                >
                  Launch demo modal
                </Button>

                <Modal show={this.state.showModal} onHide={this.close}>
                  <Modal.Header closeButton>
                    <Modal.Title>Sourland Mountain Preserve Climbs</Modal.Title>
                  </Modal.Header>
                  <Modal.Body>
                    <h4>Sourland Mountain Preserve</h4>
                    <p>Climbing is allowed in blank, but watch out for blank.</p>

                    <h4>This is a Popover</h4>
                    <p>there is a <OverlayTrigger overlay={popover}><a href="#">popover</a></OverlayTrigger> here</p>

                    <h4>Tooltips in a modal</h4>
                    <p>there is a <OverlayTrigger overlay={tooltip}><a href="#">tooltip</a></OverlayTrigger> here</p>
                  </Modal.Body>
                  
                  <Modal.Footer>
                    <Button onClick={this.close}>Close</Button>
                  </Modal.Footer>
                </Modal>
            </div>
        );
    }
}

2 个答案:

答案 0 :(得分:1)

在实现Dandy的构造函数修复之后,我使用Daniel Andrews's ES6 React GMap Component post作为参考重写了ES6中的map组件。

由于此组件用于Meteor 1.4应用程序,因此我必须使用严格的ES6(安德鲁示例中没有ES5或ES7 +)

export class Maps extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        userPosition: {lat: 40.7128, lng: -74.0059},
        defaultCenter: {
            lat: 40.7128,
            lng: -74.0059
        },
        zoom: 10,
        showModal: false,
    };
    this.close = this.close.bind(this);
    this.open = this.open.bind(this);
}

componentDidMount() {
  this.map = this.createMap()
  this.marker = this.createMarker()
  this.infoWindow = this.createInfoWindow()

  google.maps.event.addListener(this.map, 'zoom_changed', ()=> this.handleZoomChange())

  google.maps.event.addListener(this.marker, 'click', ()=> this.handleMarkerClick())
}

componentDidUnMount() {
  google.maps.event.clearListeners(map, 'zoom_changed')
}

createMap() {
  let mapOptions = {
    zoom: this.state.zoom,
    center: this.mapCenter()
  }
  return new google.maps.Map(this.refs.mapCanvas, mapOptions)
}

mapCenter() {
  return new google.maps.LatLng(
    this.state.defaultCenter.lat,
    this.state.defaultCenter.lng
  )
}

createMarker() {
  return new google.maps.Marker({
    position: this.mapCenter(),
    map: this.map
  })
}

createInfoWindow() {
  let contentString = "<div class='InfoWindow'>I'm a Window that contains Info Yay</div>"
  return new google.maps.InfoWindow({
    map: this.map,
    anchor: this.marker,
    content: contentString
  })
}

handleMarkerClick(){
    console.log("ow");
    this.setState({
      showModal: true
    });
    this.infowindow.open(map, marker);
}

handleZoomChange() {
  this.setState({
    zoom: this.map.getZoom()
  })
}

close() {
    this.setState({ showModal: false });
  }

open() {
    this.setState({ showModal: true });
  }

  render() {

    const popover = (
      <Popover id="modal-popover" title="popover">
        very popover. such engagement
      </Popover>
    );
    const tooltip = (
      <Tooltip id="modal-tooltip">
        wow.
      </Tooltip>
    );

    return <div>
    <div className="GMap">
      <div className='UpdatedText'>
        <p>Current Zoom: { this.state.zoom }</p>
      </div>
      <div className='GMap-canvas' ref="mapCanvas">
      </div>
    </div>

      <Modal show={this.state.showModal} onHide={this.close}>
        <Modal.Header closeButton>
          <Modal.Title>Sourland Mountain Preserve Climbs</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <h4>Sourland Mountain Preserve</h4>
          <p>Climbing is allowed in blank, but watch out for blank.</p>

          <h4>This is a Popover</h4>
          <p>there is a <OverlayTrigger overlay={popover}><a href="#">popover</a></OverlayTrigger> here</p>

          <h4>Tooltips in a modal</h4>
          <p>there is a <OverlayTrigger overlay={tooltip}><a href="#">tooltip</a></OverlayTrigger> here</p>

          <hr />

        </Modal.Body>
        <Modal.Footer>
          <Button onClick={this.close}>Close</Button>
        </Modal.Footer>
      </Modal>
    </div>
  }

}

答案 1 :(得分:0)

从您的代码中,您似乎没有在构造函数中设置正确的状态。结果,'showModal&#39;不可访问/不存在。

确保构造函数配置为设置组件的状态:

更改:

<add key="log4net.Internal.Debug" value="true"/>

进入这个:

constructor(props) {
    super(props);
        userPosition: {lat: 40.7128, lng: -74.0059},
        defaultCenter: {
            lat: 40.7128,
            lng: -74.0059
        },
        showModal: false,
    };

这应该确保使用constructor(props) { super(props); this.state = { userPosition: {lat: 40.7128, lng: -74.0059}, defaultCenter: { lat: 40.7128, lng: -74.0059 }, showModal: false } }; 正确地将组件的状态从true更新为false。