-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] Accessing Model sub-structures #47
Comments
Couldn't you use arrays and bind array elements to the ui elements? Vuejs accepts There are currently two caveats:
I have currently submitted a PR, that remedies the first two shortcomings, but it is still in development. If you want to give it a try, install
It also imports OffsetArray, which supports user-specific indexing. (Inn the final version you might have to import OffsetArrays yourself, as we are trying to keep the number of dependencies as small as possible.)
The If you want to bind a toggle element then you have to take care that you provide a Symbol for model binding
Or you could use the
I put it here rather for showing the API of stipple elements.
|
Looks amazing @hhaensel !
Isn't this a known "limitation" of Observables.jl? See here. The solution is just to have a |
Thanks for your response! Indeed, this seems like a possible way to go, but I'm not satisfied 100% with the answer because that is just a workaround, it's not a solution. Is it really not possible to use a structure? The added benefit is that I could use multiple dispatch on the Julia side and write less code, and I could more easily test it. I noticed that even if I use structures, you correctly generate the javascript code to describe those nested structures (using dicts). What is missing is 1) the methods to allow editing directly the subfields and 2) the possibility in the Julia side to access them... |
Maybe the solution would allow users to define their own widgets. So say I have a struct to control a thing: struct Thing
height::Float64
good::Bool
name::String
end and you'd like to define a new widgets that is a combination of Quasar widgets (e.g. a slider, a checkbox, and input) in some specific layout (e.g. vertical?). Then it would be cool if there was a way for the user to define the connection that updates an instance of I think GtkReactive had done something similar, or maybe it was old old Makie... |
Yes indeed, that would be very nice to have... |
That can be done and it's actually how Stipple works internally. If you think about Stipple's types, eg The Julia -> JS serialization is done with The JS -> Julia un-serialization is done by specializing Actual code for function Stipple.render(rd::RangeData{T}, fieldname::Union{Symbol,Nothing} = nothing) where {T,R}
Dict(:min => rd.range.start, :max => rd.range.stop)
end
function Base.parse(::Type{RangeData{T}}, d::Dict{X,Y}) where {T,X,Y}
RangeData(d["min"]:d["max"])
end |
Other thoughts: |
1 - Maybe so, but I find that in many cases multiple dispatch helps reduce the amount of code and makes reasoning around it simpler... But maybe not in this case. 2 - How does bind work in this case? 3 - will do. I'm simply building a front-end for sacred, a bit like Omniboard, though only for my simulations and not for arbitrary data, and a bit simpler... By the way, is there a way to have observer function print errors to the REPL? |
1 - yes, I also believe that types are more expressive, vs dicts (eg a 2 - I haven't actually tried it but it should work with 3 - nice, thanks! 5 - errors in REPL - I think this came up in the past as well, can't remember how/if it has been solved. That part is handled by |
btw, if Stipple would use |
@yakir12 what part of the stack do you have in mind? Do you have an example? |
I admit I thought this was more prevalent, but one example is |
There is one major difficulty in using NamedTuples, although I really like the approach; the set of allowed characters is smaller. In particular, you cannot easily code dicts that contain I have currently introduced a translator (reviver) for js functions, which is under testing in hh-newReactive. We could, of course, define special characters/sequences, and replace them by the reviver. I remember that usage of NTs instead of If we feel that performance starts to be a problem, we might invite some compiler people for discussion. BTW, @essenciary , have you registered for a talk during JuliaCon? |
Well, it is a similar thing to what you refer to, but on the front-end side. To address the problem on the Stipple side I already proposed to use |
@hhaensel I don't fully understand the impact of the proposed changes at #43 (comment) - for start, what is "the current |
I did not submit a Stipple talk proposal for this year as I didn't feel that it would've brought enough benefits/novelty compared to the 2020 Stipple talk. But one about Stipple v1 in 2022, with a stable API, docs, a mature packages ecosystem, UI builder, etc would be a killer! :D |
I don't know enough of Stipple's internal to talk about it, so if what I say below makes no sense please ignore it, but I guess that you are referring to the fact that you modify those objects differently, right? However, Why can't you support NamedTuples and Dicts? For example, if you define stipple_getproperty(x, key) = getproperty(x, key)
stipple_getproperty(x, key::AbstractString) = stipple_getproperty(x, Symbol(key))
stipple_getproperty(x::Dict, key::Symbol) = x[key] and similar |
For me it's still not clear what Dicts are we talking about. Is this about I believe it's useful to brainstorm features and improvements as they pop-up in different contexts, but to address them properly we should set separate issues for each individual topic with a well defined problem and a minimal working example. |
That's the one, I'm talking of. If I understand it correctly, the aim of this definition is to update the content of the observable while suppressing the listeners that are listed in We could then define
which would make it possible to change elements by
It would hold for any type that exposes |
Hmmm... however, the important part here is that this overwrites/specializes the original |
@hhaensel ok I remembered. When a value is pushed from the front we need to update it in our model and we need to trigger all its user defined observers/handlers with the exception of the Stipple data sync handler (to avoid that the value received from the front is pushed to the front again). Makes sense? |
That's how I understood it and that's what I implemented with withoutwatchers mixing (EDIT: for the frontend). I think, if we split the set index! for zero keys and with keys (arg1, args...) we should get along. I'll give it a try then |
It's done and, as far as I can see, works like a charm. See also my post in PR 43. So now we have
|
@hhaensel You rock! I'll switch to the branch and run our demos. Hopefully we'll have CI and automated UI tests in a few weeks time too :D |
It's never too late for a post-deadline talk 😉 BTW, just added the constructor |
I link here my latest implementation of nested indexing (#79, #81). This allows to change elements of dictionaries and arrays just by adding consecutive indices, e.g. julia> model.plot_options[:chart, :type] = :line
Dict{Symbol, Any} with 1 entry:
:type => :line The element is changed correctly and only the that very element is updated via webchannel. |
Hello!
Let me begin by thanking you for the amazing framework, I started playing with Stipple two days ago and I find it rather pleasant to use (except for the lack of docstrings, but well, that's life).
I am trying to develop a fairly complex dashboard to monitor my simulations, and would like to split my model, which otherwise will have more than 100 fields, into several sub-structures for code clarity and maintainability/sanity.
However, I need to be able to read/set those fields from some UI elements like Selector, Checkboxes or plot them.
Is it possible to turn something like
into something like
and still use it from the ui?
The text was updated successfully, but these errors were encountered: