Skip to content

Commit

Permalink
feat(GoogleMap): hookup event listeners to map instance
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchentw committed Oct 24, 2014
1 parent 543f467 commit ff1a7a8
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 16 deletions.
7 changes: 6 additions & 1 deletion client/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ var Body = React.createClass({
return <div>
<GoogleMap
googleMapsApi={this.state.googleMapsApi}
mapOptions={this.state.mapOptions}>
mapOptions={this.state.mapOptions}
onClick={this._handle_map_click}>
</GoogleMap>
</div>
},

_handle_map_click () {
console.log("_handle_map_click");
}
});

Expand Down
80 changes: 65 additions & 15 deletions src/GoogleMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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 <div ref="mapCanvas" style={{width:"100%", height:400}} />;
}
Expand Down

0 comments on commit ff1a7a8

Please sign in to comment.