@@ -215,27 +215,50 @@ def _render_model_attributes(
215
215
h = attrs .pop (k )
216
216
handlers_by_event [k ] = h
217
217
218
- handlers_by_target : Dict [str , EventHandler ] = {}
219
- model_event_targets : Dict [str , _ModelEventTarget ] = {}
218
+ if old_state is None :
219
+ self ._render_model_event_handlers_without_old_state (
220
+ new_state , handlers_by_event
221
+ )
222
+ return None
223
+
224
+ for old_event in set (old_state .targets_by_event ).difference (handlers_by_event ):
225
+ old_target = old_state .targets_by_event [old_event ]
226
+ del self ._event_handlers [old_target ]
227
+
228
+ if not handlers_by_event :
229
+ return None
230
+
231
+ model_event_handlers = new_state .model ["eventHandlers" ] = {}
220
232
for event , handler in handlers_by_event .items ():
221
- target = f"{ new_state .key_path } /{ event } "
222
- handlers_by_target [target ] = handler
223
- model_event_targets [event ] = {
233
+ target = old_state .targets_by_event .get (event , id (handler ))
234
+ new_state .targets_by_event [event ] = target
235
+ self ._event_handlers [target ] = handler
236
+ model_event_handlers [event ] = {
224
237
"target" : target ,
225
238
"preventDefault" : handler .prevent_default ,
226
239
"stopPropagation" : handler .stop_propagation ,
227
240
}
228
241
229
- if old_state is not None :
230
- for old_target in set (old_state .event_targets ).difference (
231
- handlers_by_target
232
- ):
233
- del self ._event_handlers [old_target ]
242
+ return None
243
+
244
+ def _render_model_event_handlers_without_old_state (
245
+ self ,
246
+ new_state : _ModelState ,
247
+ handlers_by_event : Dict [str , EventHandler ],
248
+ ) -> None :
249
+ if not handlers_by_event :
250
+ return None
234
251
235
- if model_event_targets :
236
- new_state .event_targets .update (handlers_by_target )
237
- self ._event_handlers .update (handlers_by_target )
238
- new_state .model ["eventHandlers" ] = model_event_targets
252
+ model_event_handlers = new_state .model ["eventHandlers" ] = {}
253
+ for event , handler in handlers_by_event .items ():
254
+ target = hex (id (handler ))[2 :]
255
+ new_state .targets_by_event [event ] = target
256
+ self ._event_handlers [target ] = handler
257
+ model_event_handlers [event ] = {
258
+ "target" : target ,
259
+ "preventDefault" : handler .prevent_default ,
260
+ "stopPropagation" : handler .stop_propagation ,
261
+ }
239
262
240
263
return None
241
264
@@ -283,8 +306,9 @@ def _render_model_children(
283
306
self ._unmount_model_states (list (old_child_states .values ()))
284
307
285
308
new_children = new_state .model ["children" ] = []
286
- for index , (key , (child_type , child )) in enumerate (
287
- raw_typed_children_by_key .items ()
309
+ for index , (key , (child_type , child )) in (
310
+ # we can enumerate this because dict insertion order is preserved
311
+ enumerate (raw_typed_children_by_key .items ())
288
312
):
289
313
if child_type is DICT_TYPE :
290
314
old_child_state = old_state .children_by_key .get (key )
@@ -348,9 +372,8 @@ class _ModelState:
348
372
"life_cycle_hook" ,
349
373
"component" ,
350
374
"patch_path" ,
351
- "key_path" ,
352
375
"model" ,
353
- "event_targets " ,
376
+ "targets_by_event " ,
354
377
"children_by_key" ,
355
378
"__weakref__" ,
356
379
)
@@ -369,16 +392,15 @@ def __init__(
369
392
370
393
if parent is not None :
371
394
self ._parent_ref = ref (parent )
372
- self .key_path = f"{ parent .key_path } /{ key } "
373
395
self .patch_path = f"{ parent .patch_path } /children/{ index } "
374
396
else :
375
- self .key_path = self . patch_path = ""
397
+ self .patch_path = ""
376
398
377
399
if life_cycle_hook is not None :
378
400
self .life_cycle_hook = life_cycle_hook
379
401
self .component = life_cycle_hook .component
380
402
381
- self .event_targets : Set [str ] = set ()
403
+ self .targets_by_event : Dict [str , str ] = {}
382
404
self .children_by_key : Dict [str , _ModelState ] = {}
383
405
384
406
@property
0 commit comments