fonsp / Pluto.jl

🎈 Simple reactive notebooks for Julia
https://plutojl.org/
MIT License
5.01k stars 293 forks source link

@bind for Observables #2895

Open aplavin opened 7 months ago

aplavin commented 7 months ago

Observables.jl is a widely used package defining, well Observable(). It would be useful to bind Pluto UI elements to Observables, so that supporting libraries (such as Makie) update values efficiently.

I tried to make a macro @bindobs that works similar to @bind but defines an observable. I didn't manage to implement it properly, so would be happy to know if I missed something, or is such a thing not supported yet. What I achieved is a "two-part" macro:

macro bindobs(def::Symbol, element)
    defraw = Symbol(def, :____raw)
    quote
        elt = $element
        $(esc(def)) = Observable(get(elt))
        @bind $defraw elt
    end
end

macro bindobs_(def::Symbol)
    defraw = Symbol(def, :____raw)
    :($(esc(def))[] = $(esc(defraw)))
end

then, in one cell do @bindobs myval Slider(...) and in another cell @bindobs_ myval.

Can this be done in a single cell?

oschulz commented 3 months ago

Having Observables.jl integration in Pluto would be very nice, I think.

fonsp commented 3 months ago

Hey @aplavin ! Could you give this a try with @use_state from PlutoHooks.jl? That should allow a single-cell macro.

Prototype:

# ╔═╡ b0d2f6ee-53d9-11ef-1488-89e1652a0a68
using Observables

# ╔═╡ 5826d8f7-9aeb-438d-b426-ac166ab9800c
using PlutoHooks

# ╔═╡ dcc6a1e5-29ea-4f57-9bc6-cbaa923c0e2c
obs = Observable(0)

# ╔═╡ d2796325-fae8-4080-9178-35e115ee7cd7
zzz = let
    state, set_state = @use_state(obs[])

    Observables.on(set_state, obs)
    @use_effect([]) do

        return () -> Observables.off(set_state)
    end

    state
end

# ╔═╡ b7b29cef-bee6-4258-b411-968c0f1f9667
rand(zzz)

# ╔═╡ 5e6e0ef9-7387-469b-97a7-5d552e0f2eab
obs[] = 3

https://github.com/user-attachments/assets/07b9ebbc-a237-4655-848a-83c4322b5348

damianodegaspari commented 2 months ago

If I am not mistaken, is this also a related and still open issue? https://github.com/fonsp/Pluto.jl/issues/155# The suggestion by @cdsousa in https://github.com/fonsp/Pluto.jl/issues/155#issuecomment-912945123 is still working for me.