Closed undoZen closed 8 years ago
Yes, you can "pipe" a property into an AbstractMutable
like that. In your case, piping "urlhash" to a "rootAtom", it is likely to be safe to use an onValue
subscription for the purpose, because the "pipe" is only setup once and is live for the duration of the program. This may be something that you already understand, but, in general, however, one must be careful with onValue
to avoid leaking subscriptions. The description starting here might also interest you.
No, there is no shortcut for that out of the box. In my JS projects I often have a file like monkey.js
where I monkey patch libraries like Kefir with extensions I want. In my current project, I have (among others) the following extensions:
const o = Kefir.Observable.prototype
o.startWith = function (v) {return Kefir.constant(v).concat(this)}
o.mapK = function (f) {return K(this, f)}
o.view = function (...ls) {return K(this, L.get(P(...ls)))}
o.do = function (action) {return this.mapK(v => {action(v); return null}).startWith(null)}
o.into = function (settable) {return this.do(v => settable.set(v))}
The into
operation above returns a Kefir property that immediately and always produces null
. Such a property can be injected into Karet JSX directly and one use that to create components that provide outputs via reactive variables. Here is an example of a BMI
component that takes width
and height
as input-output variables and bmi
as an output variable:
const Slider = ({title, units, value, ...props}) =>
<div>
<div>{title}: {value}{units}</div>
<input type="range" {...props} {...bind({value})}/>
</div>
const BMI = ({weight = Atom(80), height = Atom(180), bmi = Atom()}) =>
<div>
<Slider title="Weight" units="kg" min={40} max={140} value={weight}/>
<Slider title="Height" units="cm" min={140} max={210} value={height}/>
<div>BMI: {bmi}</div>
{K(height, weight, (h, w) => Math.round(w/(h * h * 0.0001))).into(bmi)}
</div>
Note that in the above there is no call to onValue
—It is handled by Karet, which subscribes to properties when components are mounted and unsubscribes when they are unmounted.
Outside of BMI
one can now share the bmi
variable with other components if desired.
This form of flexible wiring via the use of reactive variables and side-effecting properties is somewhat unorthodox and I have not been doing it previously. I'm currently in the process of considering whether it would make sense to introduce alternatives to or redefine Atom
and K
with slightly different semantics that would make the above kind of wiring behave better.
any alternative or shortcut?