##// END OF EJS Templates
Update widget serializer/unserializer to allow custom serialization on a trait-by-trait basis....
Jason Grout -
Show More
@@ -195,8 +195,16 b' class Widget(LoggingConfigurable):'
195 195 A single property's name to get.
196 196 """
197 197 keys = self.keys if key is None else [key]
198 return {k: self._pack_widgets(getattr(self, k)) for k in keys}
199
198 state = {}
199 for k in keys:
200 f = self.trait_metadata(k, 'to_json')
201 value = getattr(self, k)
202 if f is not None:
203 state[k] = f(value)
204 else:
205 state[k] = self._serialize_trait(value)
206 return state
207
200 208 def send(self, content):
201 209 """Sends a custom msg to the widget model in the front-end.
202 210
@@ -280,7 +288,11 b' class Widget(LoggingConfigurable):'
280 288 """Called when a state is received from the front-end."""
281 289 for name in self.keys:
282 290 if name in sync_data:
283 value = self._unpack_widgets(sync_data[name])
291 f = self.trait_metadata(name, 'from_json')
292 if f is not None:
293 value = f(sync_data[name])
294 else:
295 value = self._unserialize_trait(sync_data[name])
284 296 with self._lock_property(name, value):
285 297 setattr(self, name, value)
286 298
@@ -299,31 +311,34 b' class Widget(LoggingConfigurable):'
299 311 """Called when a view has been displayed for this widget instance"""
300 312 self._display_callbacks(self, **kwargs)
301 313
302 def _pack_widgets(self, x):
303 """Recursively converts all widget instances to model id strings.
314 def _serialize_trait(self, x):
315 """Serialize a trait value to json
304 316
305 Children widgets will be stored and transmitted to the front-end by
306 their model ids. Return value must be JSON-able."""
317 Traverse lists/tuples and dicts and serialize their values as well.
318 Replace any widgets with their model_id
319 """
307 320 if isinstance(x, dict):
308 return {k: self._pack_widgets(v) for k, v in x.items()}
321 return {k: self._serialize_trait(v) for k, v in x.items()}
309 322 elif isinstance(x, (list, tuple)):
310 return [self._pack_widgets(v) for v in x]
323 return [self._serialize_trait(v) for v in x]
311 324 elif isinstance(x, Widget):
312 325 return x.model_id
313 326 else:
314 327 return x # Value must be JSON-able
315 328
316 def _unpack_widgets(self, x):
317 """Recursively converts all model id strings to widget instances.
329 def _unserialize_trait(self, x):
330 """Convert json values to objects
318 331
319 Children widgets will be stored and transmitted to the front-end by
320 their model ids."""
332 We explicitly support converting valid string widget UUIDs to Widget references.
333 """
321 334 if isinstance(x, dict):
322 return {k: self._unpack_widgets(v) for k, v in x.items()}
335 return {k: self._unserialize_trait(v) for k, v in x.items()}
323 336 elif isinstance(x, (list, tuple)):
324 return [self._unpack_widgets(v) for v in x]
325 elif isinstance(x, string_types):
326 return x if x not in Widget.widgets else Widget.widgets[x]
337 return [self._unserialize_trait(v) for v in x]
338 elif isinstance(x, string_types) and x in Widget.widgets:
339 # we want to support having child widgets at any level in a hierarchy
340 # trusting that a widget UUID will not appear out in the wild
341 return Widget.widgets[x]
327 342 else:
328 343 return x
329 344
General Comments 0
You need to be logged in to leave comments. Login now