From ff1a7a8acf7534e61036ec6cf2c75b5a79918143 Mon Sep 17 00:00:00 2001 From: Tom Chen Date: Thu, 23 Oct 2014 20:41:40 +0800 Subject: [PATCH] feat(GoogleMap): hookup event listeners to map instance --- client/scripts/index.js | 7 +++- src/GoogleMap.js | 80 +++++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/client/scripts/index.js b/client/scripts/index.js index 71d534cb..26b72b8e 100755 --- a/client/scripts/index.js +++ b/client/scripts/index.js @@ -32,9 +32,14 @@ var Body = React.createClass({ return
+ mapOptions={this.state.mapOptions} + onClick={this._handle_map_click}>
+ }, + + _handle_map_click () { + console.log("_handle_map_click"); } }); diff --git a/src/GoogleMap.js b/src/GoogleMap.js index 07fc9ddd..d45b8102 100644 --- a/src/GoogleMap.js +++ b/src/GoogleMap.js @@ -6,6 +6,26 @@ var mapsNullObject = { }; +var EVENT_MAP = {}; +var EVENT_LIST = "bounds_changed center_changed click dblclick drag dragend dragstart heading_changed idle maptypeid_changed mousemove mouseout mouseover projection_changed resize rightclick tilesloaded tilt_changed zoom_changed" + .split(" ") + .map(toEventList, EVENT_MAP); + +function toEventList (name) { + var eventName = toEventName(name); + this[eventName] = name; + return eventName; +} + +function toEventName(name) { + return `on${ name + .replace(/^(.)/, groupToUpperCase) + .replace(/_(.)/g, groupToUpperCase) }`; +} + +function groupToUpperCase (match, group) { + return group.toUpperCase(); +} module.exports = React.createClass({ displayName: "GoogleMap", @@ -19,42 +39,72 @@ module.exports = React.createClass({ getInitialState () { return { googleMapsApi: this.props.googleMapsApi || mapsNullObject, - map: null + map: null, + eventNames: [] }; }, + componentWillMount () { + this.setState({ + eventNames: this._collect_event_names(this.props) + }); + }, + componentWillReceiveProps (nextProps) { var {googleMapsApi} = nextProps; + var newState = {}; + if (mapsNullObject !== googleMapsApi) { - this.setState({ - googleMapsApi - }); + newState.googleMapsApi = googleMapsApi; } + newState.eventNames = this._collect_event_names(nextProps); + this.setState(newState); }, componentDidMount () { - this._initGoogleMaps(this.state.googleMapsApi); + this._init_google_maps(this.state.googleMapsApi); }, componentDidUpdate () { - this._initGoogleMaps(this.state.googleMapsApi); + this._init_google_maps(this.state.googleMapsApi); }, - _initGoogleMaps (googleMapsApi) { - if (this.state.map || mapsNullObject === googleMapsApi) { return; } - var map = new googleMapsApi.Map( - this.refs.mapCanvas.getDOMNode(), - this.props.mapOptions - ); - this.setState({ - map - }); + componentWillUnmount () { + var {googleMapsApi, map} = this.state; + this._clear_listeners(googleMapsApi, map); }, render () { return this._render(this.props, this.state); }, + _init_google_maps (googleMapsApi) { + if (mapsNullObject === googleMapsApi) { return; } + var {map, eventNames} = this.state; + if (!map) { + map = new googleMapsApi.Map( + this.refs.mapCanvas.getDOMNode(), + this.props.mapOptions + ); + this.setState({ map }); + } + this._clear_listeners(googleMapsApi, map); + eventNames.forEach((eventName) => { + var name = EVENT_MAP[eventName]; + googleMapsApi.event.addListener(map, name, this.props[eventName]); + }); + }, + + _collect_event_names (props) { + return EVENT_LIST.filter((eventName) => { + return eventName in props; + }); + }, + + _clear_listeners (googleMapsApi, map) { + googleMapsApi.event.clearInstanceListeners(map); + }, + _render (props, state) { return
; }