Observables
Observables are like Ref
s but you can listen to changes.
julia> using Observables
julia> observable = Observable(0)
Observable{Int64}("ob_01", 0, Any[])
julia> h = on(observable) do val
println("Got an update: ", val)
end
#1 (generic function with 1 method)
julia> observable[] = 42
Got an update: 42
42
To get the value of an observable index it with no arguments
julia> observable[]
42
To remove a handler use off
with the return value of on
:
julia> off(observable, h)
How is it different from Reactive.jl?
The main difference is Signal
s are manipulated mostly by converting one signal to another. For example, with signals, you can construct a changing UI by creating a Signal
of UI objects and rendering them as the signal changes. On the other hand, you can use an Observable both as an input and an output. You can arbitrarily attach outputs to inputs allowing structuring code in a signals-and-slots kind of pattern.
Another difference is Observables are synchronous, Signals are asynchronous. Observables may be better suited for an imperative style of programming.
API
Observables.Observable
— Type.Like a Ref
but updates can be watched by adding a handler using on
.
Observables.on
— Method.on(f, o::Observable)
Adds function f
as listener to o
. Whenever o
's value is set via o[] = val
f
is called with val
.
Observables.off
— Method.off(o::Observable, f)
Removes f
from listeners of o
.
Base.setindex!
— Method.o[] = val
Updates the value of an Observable
to val
and call its listeners.
Base.getindex
— Method.o[]
Returns the current value of o
.
Observables.onany
— Method.onany(f, args...)
Calls f
on updates to any oservable refs in args
. args
may contain any number of Observable
ojects. f
will be passed the values contained in the refs as the respective argument. All other ojects in args
are passed as-is.
Base.map!
— Method.map!(f, o::Observable, args...)
Updates o
with the result of calling f
with values extracted from args. args
may contain any number of Observable
ojects. f
will be passed the values contained in the refs as the respective argument. All other ojects in args
are passed as-is.
Observables.connect!
— Method.connect!(o1::Observable, o2::Observable)
Forward all updates to o1
to o2
Base.map
— Method.map(f, o::Observable, args...)
Creates a new oservable ref which contains the result of f
applied to values extracted from args. The second argument o
must be an oservable ref for dispatch reasons. args
may contain any number of Observable
ojects. f
will be passed the values contained in the refs as the respective argument. All other ojects in args
are passed as-is.