Skip to content

Commit

Permalink
fixes: #246
Browse files Browse the repository at this point in the history
The layout was not producing the correct path in its update for element which were
not direct children of eachother.
  • Loading branch information
rmorshea committed Oct 15, 2020
1 parent d67e2be commit fe56b77
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
23 changes: 18 additions & 5 deletions idom/core/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
Tuple,
Mapping,
NamedTuple,
Optional,
Any,
Set,
Iterator,
Expand Down Expand Up @@ -154,29 +155,41 @@ def _render_element(self, element_state: ElementState) -> Dict[str, Any]:
return element_state.model

def _render_model(
self, element_state: ElementState, model: Mapping[str, Any]
self,
element_state: ElementState,
model: Mapping[str, Any],
path: Optional[str] = None,
) -> Dict[str, Any]:
if path is None:
path = element_state.path

serialized_model: Dict[str, Any] = {}
event_handlers = self._render_model_event_targets(element_state, model)
if event_handlers:
serialized_model["eventHandlers"] = event_handlers
if "children" in model:
serialized_model["children"] = self._render_model_children(
element_state, model["children"]
element_state, model["children"], path
)
return {**model, **serialized_model}

def _render_model_children(
self, element_state: ElementState, children: Union[List[Any], Tuple[Any, ...]]
self,
element_state: ElementState,
children: Union[List[Any], Tuple[Any, ...]],
path: str,
) -> List[Any]:
resolved_children: List[Any] = []
for index, child in enumerate(
children if isinstance(children, (list, tuple)) else [children]
):
if isinstance(child, dict):
resolved_children.append(self._render_model(element_state, child))
child_path = f"{path}/children/{index}"
resolved_children.append(
self._render_model(element_state, child, child_path)
)
elif isinstance(child, AbstractElement):
child_path = f"{element_state.path}/children/{index}"
child_path = f"{path}/children/{index}"
child_state = self._create_element_state(child, child_path, save=True)
resolved_children.append(self._render_element(child_state))
element_state.child_elements_ids.append(id(child))
Expand Down
21 changes: 21 additions & 0 deletions tests/test_core/test_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,24 @@ def AnElement():
pass # the render should still be rendering since we only update once

assert run_count.current == 2


async def test_update_path_to_element_that_is_not_direct_child_is_correct():
hook = HookCatcher()

@idom.element
def Parent():
return idom.html.div(idom.html.div(Child()))

@idom.element
@hook.capture
def Child():
return idom.html.div()

async with idom.Layout(Parent()) as layout:
await layout.render()

hook.current.schedule_render()

update = await layout.render()
assert update.path == "/children/0/children/0"

0 comments on commit fe56b77

Please sign in to comment.