Created
February 3, 2019 23:23
-
-
Save valerysntx/35faa243d9782a0fcbeb734cb802164c to your computer and use it in GitHub Desktop.
knockout-react.js
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
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