@@ -106,13 +106,7 @@ VBox([s1, s2])
106
106
log ( "handleIpwidgetsTableChange" , { model_id, type } ) ;
107
107
switch ( type ) {
108
108
case "state" :
109
- // Overall state is only used for creating widget when it is
110
- // rendered for the first time as part of Environment.getSerializedModelState
111
- // So do NOT call it again here on any change. Updates for RTC use
112
- // type='value'. Doing this causes a lot of noise, which e.g., completely
113
- // breaks rendering using the threejs custom widgets, e.g., this breaks;
114
- // from pythreejs import DodecahedronGeometry; DodecahedronGeometry()
115
- // await this.ipywidgets_state_StateChange(model_id);
109
+ await this . ipywidgets_state_StateChange ( model_id ) ;
116
110
break ;
117
111
case "value" :
118
112
await this . ipywidgets_state_ValueChange ( model_id ) ;
@@ -129,15 +123,28 @@ VBox([s1, s2])
129
123
}
130
124
} ;
131
125
132
- // private ipywidgets_state_StateChange = async (model_id: string) => {
133
- // log("ipywidgets_state_StateChange: ", model_id);
134
- // const state = this.ipywidgets_state.getSerializedModelState(model_id);
135
- // log("ipywidgets_state_StateChange: state=", JSON.stringify(state));
136
- // if (state == null) {
137
- // return;
138
- // }
139
- // await this.updateModel(model_id, state!, false);
140
- // };
126
+ private ipywidgets_state_StateChange = async ( model_id : string ) => {
127
+ // Overall state is only used for creating widget when it is
128
+ // rendered for the first time as part of Environment.getSerializedModelState,
129
+ // if it is called. Some widgets though need to get created, but they are
130
+ // never rendered, so we only know about them due to state change.
131
+ //
132
+ // First: We only do this once if getSerializedModelState didn't happen. Updates for RTC use
133
+ // type='value'. Doing this causes a lot of noise, which e.g., completely
134
+ // breaks rendering using the threejs custom widgets, e.g., this breaks;
135
+ // from pythreejs import DodecahedronGeometry; DodecahedronGeometry()
136
+ //
137
+ // Second: This example shows that sometimes getSerializedModelState is never called, so
138
+ // it's important to call this in some cases:
139
+ // from ipywidgets import VBox, jsdlink, IntSlider, Button; s1 = IntSlider(max=200, value=100); s2 = IntSlider(value=40); VBox([s1, s2])
140
+ // jsdlink((s1, 'value'), (s2, 'max'))
141
+ //
142
+
143
+ // The solution: make sure the model gets created if state change is called.
144
+ // This results in getSerializedModelState being called and causes no
145
+ // problems if it were getting called anyways and works in both cases above.
146
+ await this . manager . get_model ( model_id ) ;
147
+ } ;
141
148
142
149
private updateModel = async (
143
150
model_id : string ,
0 commit comments