Observables
Observables are like Refs 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
42To get the value of an observable index it with no arguments
julia> observable[]
42To 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 Signals 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[] = valUpdates 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.