Created
August 12, 2016 13:28
-
-
Save flenter/9dd88b053be79468a87740954bf41171 to your computer and use it in GitHub Desktop.
Backbone-wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A component to wrap/render backbone views. It will instantiate the backbone | |
* view with options as the main parameters. | |
* | |
* Usage: | |
* ``` | |
* import AppSettings from 'modules/app-settings'; | |
* | |
* const options = {}; | |
* | |
* <Component | |
* options={options} | |
* View={AppSettings} | |
* /> | |
* ``` | |
*/ | |
import merge from 'lodash.merge'; | |
import React, { Component, PropTypes } from 'react'; | |
class BackboneWrapper extends Component { | |
static propTypes = { | |
options: PropTypes.object, | |
View: PropTypes.func.isRequired, | |
}; | |
static defaultProps = { | |
options: {}, | |
}; | |
constructor(props) { | |
super(props); | |
this.state = {}; | |
} | |
componentDidMount() { | |
if (this.element) { | |
this.createView(); | |
} | |
} | |
componentDidUpdate() { | |
if (this.div && this.instance) { | |
// Checks if view has an updateOptions function and call it (With the options) | |
// if it returns true, the view can update itself without the need to recreate it | |
// on false: the view is recreated | |
if (this.instance.updateOptions) { | |
const options = this.getOptions(this.div); | |
if (this.instance.updateOptions(options)) { | |
// if true, then the backbone view has handled the changes correctly | |
return; | |
} | |
} | |
this.cleanupView(); | |
} | |
this.createView(); | |
} | |
componentWillUnmount() { | |
this.cleanupView(); | |
} | |
getOptions() { | |
return merge( | |
{ el: this.div }, | |
this.state || {}, | |
this.props.options | |
); | |
} | |
instance = null; | |
div = null; | |
createView() { | |
this.div = document.createElement('div'); | |
this.element.appendChild(this.div); | |
const options = this.getOptions(); | |
this.instance = new this.props.View(options); | |
} | |
cleanupView() { | |
if (this.instance) { | |
this.instance.remove(); | |
this.instance.unbind(); | |
this.instance.$el.empty(); | |
this.instance = null; | |
} | |
if (this.div) { | |
this.div = null; | |
} | |
} | |
registerElement = el => { | |
if (el && this.element && this.element !== el) { | |
/* eslint-disable no-console */ | |
console.warn('backbone-wrapper::element/ref node changed.', el); | |
/* eslint-enable no-console */ | |
} | |
this.element = el; | |
}; | |
render() { | |
return <div ref={this.registerElement}></div>; | |
} | |
} | |
export default BackboneWrapper; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment