recompose

This commit is contained in:
Will McGugan
2024-04-13 16:58:00 +01:00
parent e0a5c4dd3b
commit 443aafb2dd
2 changed files with 36 additions and 3 deletions

View File

@@ -2561,9 +2561,21 @@ class App(Generic[ReturnType], DOMNode):
Recomposing will remove children and call `self.compose` again to remount.
"""
async with self.screen.batch():
await self.screen.query("*").exclude(".-textual-system").remove()
await self.screen.mount_all(compose(self))
# async with self.screen.batch():
# await self.screen.query("*").exclude(".-textual-system").remove()
# await self.screen.mount_all(compose(self))
children_by_id = {child.id: child for child in self.children if child.id}
new_children = []
for widget in compose(self):
if (
widget.id
and (existing_widget := children_by_id.get(widget.id)) is not None
):
new_children.append(existing_widget)
existing_widget.set_reactive_state(widget.get_reactive_state())
else:
new_children.append(widget)
def _register_child(
self, parent: DOMNode, child: Widget, before: int | None, after: int | None

View File

@@ -284,6 +284,27 @@ class DOMNode(MessagePump):
self.call_later(self._initialize_data_bind)
return self
def get_reactive_state(self) -> dict[str, object]:
"""Get a dict of reactives and their values.
Returns:
A dict of reactives.
"""
state = {name: getattr(self, name) for name in self._reactives}
return state
def set_reactive_state(self, state: dict[str, object]) -> None:
"""Set reactives from a state dictionary.
Args:
state: A dict of reactive attributes.
"""
for name in self._reactives:
try:
setattr(self, name, state[name])
except KeyError:
pass
def _initialize_data_bind(self) -> None:
"""initialize a data binding.