Modifying a particular dictionary element in the model #641
-
If my model is a dictionary:
How do I update part of that? If I try something like: var current_dict = model.get("test");
const key = "k2";
if (key in current_dict) {
current_dict[key] += 1;
} else {
current_dict[key] = 1;
}
model.set("test", current_dict); then the model in the js sided is updated, but the synchronisation seems to be lost to the Python side, as if the Pyhton was synching to original model object? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Two things here. You are mutating the inner value and not calling I believe ipywidgets checks by reference for equality (to decide whether a sync message is needed), so you need to create a shallow copy for the current dict. Here is the counter example from the docs, using a dict to hold the state. import anywidget
import traitlets
class Widget(anywidget.AnyWidget):
_esm = """
function render({ model, el }) {
let btn = document.createElement("button");
btn.innerHTML = `count is ${model.get("data").value}`;
btn.addEventListener("click", () => {
const data = { ...model.get("data") }; // create a shallow copy
data.value += 1;
model.set("data", data);
model.save_changes();
});
model.on("change:data", () => {
btn.innerHTML = `count is ${model.get("data").value}`;
});
el.appendChild(btn);
}
export default { render };
"""
data = traitlets.Dict().tag(sync=True)
Widget(data={"value": 10 }) |
Beta Was this translation helpful? Give feedback.
-
HI Thanks.. yes, realised I'd omitted the Thanks again |
Beta Was this translation helpful? Give feedback.
Two things here. You are mutating the inner value and not calling
model.save_changes()
to sync back with Python.I believe ipywidgets checks by reference for equality (to decide whether a sync message is needed), so you need to create a shallow copy for the current dict. Here is the counter example from the docs, using a dict to hold the state.