Skip to content

Instantly share code, notes, and snippets.

@valerysntx
Created February 3, 2019 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save valerysntx/35faa243d9782a0fcbeb734cb802164c to your computer and use it in GitHub Desktop.
Save valerysntx/35faa243d9782a0fcbeb734cb802164c to your computer and use it in GitHub Desktop.
knockout-react.js
var KnockoutMixin = {
updateKnockout() {
// This has been bound to the dependancy chain in __koModel,
// found in the componentDidMount lifecycle stage. Changing this
// observable will cause __koModel to revaluate it's values.
this.__koTrigger(!this.__koTrigger());
},
componentDidMount() {
this.__koTrigger = ko.observable(true);
this.__koModel = ko.computed(function () {
// Magic.
// Calling this observable will add it to the dependancy
// chain for __koModel, as it is a computedObservable.
// Anytime __koTrigger is changed, such as in updateKnockout(),
// this model will revaluate
this.__koTrigger();
return {
props: this.props,
state: this.state
};
}, this); // Bind this computedObservable to the components 'this'
// Bind the __koModel view model to the components mounted DOM
// node
ko.applyBindings(this.__koModel, this.getDOMNode());
},
componentWillUnmount() {
ko.cleanNode(this.getDOMNode());
},
componentDidUpdate() {
this.updateKnockout();
}
};
/**
* Creates a ko.handler for react components, with the keyword 'react'.
* React Component passed with $ will be exposed globally.
* pass the props to computed ViewModel-Component props
*
* <ul data-bind="react: { $: ToDoList, props: { todos: todos } }><ul>
*
* ToDoList must be on window. Tip: Namespace your components in window.Components
* todos must exist in the view model that
* is bound to the nearest bound DOM node parent
*/
//
var reactHandler = ko.bindingHandlers.react = {
render: function ( el, Component, props ) {
React.render(
React.createElement(Component,props), el
);
},
init: function ( el, valueAccessor, allBindingsAccessor, viewModel, bindingContext ) {
var options = valueAccessor();
var Component = ko.unwrap(options.component || options.$);
var props = ko.toJS(options.props || viewModel);
reactHandler.render(el, Component, props);
return { controlsDescendantBindings: true };
},
update: function ( el, valueAccessor, allBindingsAccessor, viewModel, bindingContext ) {
var options = valueAccessor();
var Component = ko.unwrap(options.component || options.$);
var props = ko.toJS(options.props || viewModel);
reactHandler.render(el, Component, props);
return { controlsDescendantBindings: true };
}
};
<div data-bind="react: { $: Components.ToDoList, props: { todos: todos }}"></div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment