Partial touch on a widget view?

I’m new to ipywidgets and already started to code a custom widget with two values: a UI with one to many controls that is initialized with default values from a JSON definition (that can be quite big) and a parameter for interacting with all the controls of the custom UI; so when a control change, the parameter is updated and sent to the backend using this.model.set and touch(). The parameter change also set the default value of its corresponding control in the UI definition so that when the widget is rendered again or the page is reloaded the defaults values of the UI are initialized to the last ones set by the parameter changes. I hope my explanation make sense (because English is not my native language)…

So far it works because both the UI and the parameter are in sync with the backend, using touch() on the widget view. But now I’d like the UI to sync only one way, only once at initialization, from the backend to the front-end, to avoid sending the whole UI definition back to Python each time a control is modified, because I can easily update the UI definition in the backend using the parameter.

It is possible to control how touch (and this.model.save_changes) work in order to avoid useless messaging between the front-end and the backend? Is partial touch possible?

I found a solution.

In my widget class I define a trait without sync:
ui = List([]).tag(sync=False)

Then still in my widget class I override the _repr_mimebundle_ def from:

At the start of the overridden def I simply added: self.send_state('ui')

That was “easy”…

1 Like

But it’s a sub-optimal solution; when reloading the page, the widget doesn’t show, unless the widget is “executed” again from the cell. What I’d prefer is a way to modify the synchronization mechanism so it works one way (back-end to front-end).

I found a better solution. No change is required in Python (no need to override _repr_mimebundle), and as usual traits must be defined with .tag(sync=True) to ensure sync from backend to browser.

In Javascript, to send specific changes to the backend, I use:
this.model.sync('patch', this.model, {'attrs': {key:value}});
(the ‘attrs’ dict can have multiple key:value pairs)

For this solution to work, there should be no use of .touch() or in Javascript.

The sync method is defined here:

1 Like