浏览代码

try to automatically add new elements into the parent container of the event sender

Falko Schindler 2 年之前
父节点
当前提交
e4af10709c
共有 3 个文件被更改,包括 21 次插入6 次删除
  1. 2 1
      nicegui/events.py
  2. 13 1
      nicegui/globals.py
  3. 6 4
      nicegui/timer.py

+ 2 - 1
nicegui/events.py

@@ -230,7 +230,8 @@ def handle_event(handler: Optional[Callable], arguments: EventArguments) -> Opti
         if handler is None:
             return False
         no_arguments = not signature(handler).parameters
-        result = handler() if no_arguments else handler(arguments)
+        with globals.within_view(arguments.sender.parent_view):
+            result = handler() if no_arguments else handler(arguments)
         if is_coroutine(handler):
             if globals.loop and globals.loop.is_running():
                 create_task(result, name=str(handler))

+ 13 - 1
nicegui/globals.py

@@ -2,7 +2,8 @@ from __future__ import annotations
 
 import asyncio
 import logging
-from typing import Awaitable, Callable, Dict, List, Optional, Union
+from contextlib import contextmanager
+from typing import Awaitable, Callable, Dict, Generator, List, Optional, Union
 
 import justpy as jp
 from starlette.applications import Starlette
@@ -10,6 +11,7 @@ from uvicorn import Server
 
 from .config import Config
 from .page_builder import PageBuilder
+from .task_logger import create_task
 
 app: Starlette
 config: Optional[Config] = None
@@ -30,3 +32,13 @@ def find_route(function: Callable) -> str:
     if not routes:
         raise ValueError(f'Invalid page function {function}')
     return routes[0]
+
+
+@contextmanager
+def within_view(view: jp.HTMLBaseComponent) -> Generator[None, None, None]:
+    child_count = len(view)
+    view_stack.append(view)
+    yield
+    view_stack.pop()
+    if len(view) != child_count:
+        create_task(view.update())

+ 6 - 4
nicegui/timer.py

@@ -7,6 +7,7 @@ from typing import Callable, List
 from . import globals
 from .binding import BindableProperty
 from .helpers import is_coroutine
+from .page import find_parent_view
 from .task_logger import create_task
 
 NamedCoroutine = namedtuple('NamedCoroutine', ['name', 'coro'])
@@ -32,13 +33,14 @@ class Timer:
 
         self.active = active
         self.interval = interval
+        self.parent_view = find_parent_view()
 
         async def do_callback():
             try:
-                if is_coroutine(callback):
-                    return await callback()
-                else:
-                    return callback()
+                with globals.within_view(self.parent_view):
+                    result = callback()
+                    if is_coroutine(callback):
+                        await result
             except Exception:
                 traceback.print_exc()