ko-rx
v1.1.0
Published
Utility for converting between ko.observable and Rx.Observable
Downloads
11
Maintainers
Readme
ko-Rx
A utility for converting between ko.observable and Rx.Observable.
This package serves as a bridge between two libraries: Knockout JS and RxJS.
It offers:
- Conversion from
ko.subscribable(e.g.:ko.observable,ko.computed,ko.pureComputed) toRx.Observable. - Conversion from
Rx.Observableto a read-onlyko.computed. - A Knockout binding handler "
rx", for pushing values to anRx.Observer.
API
This utility expects you to pass a reference to Knockout's ko and RxJS's Rx. It will not write to ko or Rx unless you ask it.
To add methods to relevant prototypes, call (once):
koRx(ko, Rx, { extend: true });Knockout to Rx
To convert from a Knockout observable or computed observable, call toRxObservable(). This is useful if you have an existing Knockout observable as a source, and want to perform Rx operations on it.
Parameters
startWithCurrentValue- Iftrue, the most recent value of the subscribable is read and will be the first value of the resulting Rx Observable if it is notundefined.
Example
var koObservable = ko.observable('initial value');
koObservable.toRxObservable(true)
.take(2)
.subscribe(
function onNext(value) {
console.log(value);
},
null,
function onCompleted() {
console.log('complete');
});
koObservable('second value');
/* Which Logs:
initial value
second value
complete
*/Or, you can call the static function: Rx.Observable.fromKnockout:
var koObservable = ko.observable(0);
var rxObservable = Rx.Observable.fromKnockout(koObservable);Rx to Knockout
To convert from an Rx.Observable, simply call toKnockoutComputed(). This is useful if you need to tie an Rx Observable to your Knockout View Model.
Parameters
Since Rx Observables are usually cold, there is no "first value" to read.
options- Object:- options.forwardOnError
- Default:false. Iftrue, an error sent to the observable will be passed to the computed under theerror` property. - options.forwardOnCompleted
- Default:false. Iftrue, when the observable'sonCompletedis called,truewill be passed to the computed under thecompleted` property.
- options.forwardOnError
Example
var rxObservable = Rx.Observable.interval(100, function () {
return Math.random();
});
var viewModel = {
readOnlyComputed: rxObservable.toKnockoutComputed()
};
ko.applyBindings(viewModel, document.getElementById('demo'));<span id="demo1" data-bind="text: readOnlyComputed"></span>Knockout rx binding handler
The Knockout rx binding handler can be used to feed an Rx.Observer or Rx.Subject from your UI, declaratively.
Parameters
Required:
observer- Required, theRx.ObserverorRx.Subjecton your view model.
Optional:
event- Default:"change". The event upon which the Rx observer is passed a new value.method- Default:"onNext". The function to pass new values to. Can be"onNext","onError", or"onCompleted".first- Default:false. If true, the initial value of the element is pass tomethod.track- Default:null. If a Knockout observable is passed, the Rx observer will be updated every time the tracked observable changes.completeOnDisposal- Default:false. Iftrue, the Rx observer'sonCompletedwill be called when the DOM node is disposed.attr- Default:"value". Select an attribute to read from the element in the DOM. E.g."title".prop- Instead of anattr, select a property from the element (in JS), for example"textContent".
Examples
Basic usage:
<input id="demo2" type="text" value="0" data-bind="rx: {observer: rxSubject}" />var subject = new Rx.Subject;
ko.applyBindings({ rxSubject: subject }, document.getElementById('demo2'));
subject
.throttle(200)
.subscribe(function onNext(inputText) {
/* Will log the value of the text field each time it is changed. */
console.log(inputText);
});
Tracking a knockout observable:
<span id="demo3"
data-bind="text: koObservable(),
rx: {track: koObservable, prop: 'textContent', observer: rxSubject}">
</span>var inputField = doc.getElementById('test');
var observable = ko.observable('initial (ignored, `first` is not true)');
var subject = new Rx.Subject;
ko.applyBindings({
koObservable: observable,
rxSubject: subject
}, inputField);
observable('second value');
observable('third value');
subject.subscribe(function (value) {
console.log(value);
});
/* Logs:
second value
third value
*/Hey, stop touching to my prototypes!
Alternatively, if you do not want to write to ko or Rx, you can request all of the provided functionality by calling koRx:
var koRxFns = koRx(ko, Rx);Which provides all the functionality without writing to any prototypes. Be sure to use fn.call, to provide the appropriate this-context.
For example:
var koComputed = koRxFns.toKnockoutComputed.call(someRxObservable);
var rxObservable = koRxFns.toRxObservable.call(someKoObservable, true);
ko.bindingHandlers.rx = koRxFns.rxBinding;Compatability
Written in plain ECMAScript 5, safe to load in the browser without any transformation.
Tests
Fully unit tested with mocha, chai, sinon and jsdom. Run with:
$ npm run test-node # to test in Node.JS
$ npm run test-phantom # to test in PhantomJSLicense
MIT.
