Skip to content

Commit

Permalink
feat(Map): stateless map component
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchentw committed Nov 8, 2014
1 parent 22d9242 commit 3d3aa15
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 39 deletions.
94 changes: 55 additions & 39 deletions src/Map.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,78 @@
"use strict";
var React = require("react/addons");
var React = require("react/addons"),
deepEqual = require("deep-equal"),

var ChildMixin = require("./mixins/ChildMixin");
var EventBindingMixin = require("./mixins/EventBindingMixin");
expose_getters_from = require("./helpers/expose_getters_from"),
EventBindingMixin = require("./mixins/EventBindingMixin");

function ensure_map_created (component, createdCallback, createFactory) {
var {context} = component,
map = context.getMap(),
noMap = !map;

if (noMap && context.getApi() && createFactory) {
map = createFactory(component, context);
}
if (map) {
createdCallback(map);
if (noMap) {
component.setState({_initialized: true});
}
}
}

function create_map (component, context) {
var {Map} = context.getApi(),
map = new Map(
component.refs.mapCanvas.getDOMNode(),
component.props
);
expose_getters_from(component, Map.prototype, map);
return context._set_map(map);
}

module.exports = React.createClass({
displayName: "Map",

mixins: [ChildMixin, EventBindingMixin],
mixins: [EventBindingMixin],

contextTypes: {
getMap: React.PropTypes.func,
getApi: React.PropTypes.func,
hasMap: React.PropTypes.func,
_set_map: React.PropTypes.func
},

getInitialState () {
return {
_initialized: false
};
},

shouldComponentUpdate(nextProps, nextState) {
return !deepEqual(nextProps, this.props) || nextState._initialized !== this.state._initialized;
},

componentDidMount () {
var {context} = this;
if (!context.getApi()) return;
if (context.hasMap()) return;
this.add_listeners(this._init_map());
ensure_map_created(this, this.add_listeners, create_map);
},

componentWillUpdate () {
var {context} = this;
if (!context.getApi()) return;
if (context.hasMap()) return;
this.clear_listeners(context.getMap());
ensure_map_created(this, this.clear_listeners);
},

componentDidUpdate () {
var {context} = this;
if (!context.getApi()) return;
if (context.hasMap()) {
this.context.getMap().setOptions(this.props);
} else {
this.add_listeners(this._init_map());
}
ensure_map_created(this, (map) => {
map.setOptions(this.props);
this.add_listeners(map);
}, create_map);
},

componentWillUnmount () {
var {context} = this;
if (!context.getApi()) return;
if (context.hasMap()) return;
this.clear_listeners(context.getMap());
ensure_map_created(this, (map) => {
this.clear_listeners(map);
this.context._set_map(null);
});
},

render () {
Expand All @@ -52,22 +83,7 @@ module.exports = React.createClass({
return "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";
},

_init_map () {
var {context} = this;
var {Map} = context.getApi();
var map = new Map(
this.refs.mapCanvas.getDOMNode(),
this.props
);
this.expose_getters_from(Map.prototype, map);
return context._set_map(map);
},

_render (props, state) {
return <div ref="mapCanvas"
id={props.id}
className={props.className}
style={props.style}>
</div>;
return <div ref="mapCanvas" {...props}></div>;
}
});
9 changes: 9 additions & 0 deletions src/helpers/expose_getters_from.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use strict";

module.exports = (component, prototype, instance) => {
Object.keys(prototype).forEach((key) => {
if (key.match(/^get/) && !key.match(/Map$/)) {
component[key] = instance[key].bind(instance);
}
});
};

0 comments on commit 3d3aa15

Please sign in to comment.