Reflecting trait changes in JavaScript back to Python
See original GitHub issueHi all!
I’ve got a custom widget with some traits. This widget is basically a live stream, so I’m getting the data into JavaScript directly. I then programatically update a trait with this.model.set('mytrait', some_value)
. This works great and triggers the corresponding change:mytrait
event.
What I’d really like would be for a user in a notebook to be able to get the value of mytrait
from Python. Ideally, this would only do the serialization when the user calls widget.mytrait
in Python. Right now, if I do that, all I get is the initial default value set in Python (None
).
I thought this.touch()
or this.model.save_changes()
would help, but they did not. So how can I set a model value programatically in JavaScript and have the user in Python able to get that value on demand?
Issue Analytics
- State:
- Created 6 years ago
- Comments:13 (8 by maintainers)
And his work with the mediastream widget: https://github.com/jupyter-widgets/ipywidgets/pull/1685
Both the Python model and the JavaScript model maintain their own copy of the state. Any state change is propagated by passing events. Changes in Python are pushed to the browser straightaway, and changes in the browser are pushed to the Python side using
model.touch()
.When you call
widget.mytrait
, this just looks at the current value of themytrait
attribute in the Python side. It doesn’t call out to the JavaScript.For a fairly simple example, I suggest looking at the implementation of checkboxes:
When the user changes the
value
trait of a checkbox Python-side, a websocket message like this is sent to the browser:When the user clicks on the checkbox in the browser (line 116), the corresponding
value
attribute in the browser-side model is updated. The model is then touched, which causes it to propagate its updated state back to the Python by sending this message:You can view the websocket frames in your browser console (at least on Chrome).