Browse Source

Merge pull request #2268 from zauberzeug/refreshable-method

Introduce `ui.refreshable_method`
Falko Schindler 1 year ago
parent
commit
57fb4a6ac7
3 changed files with 17 additions and 4 deletions
  1. 13 1
      nicegui/functions/refreshable.py
  2. 2 1
      nicegui/ui.py
  3. 2 2
      tests/test_refreshable.py

+ 13 - 1
nicegui/functions/refreshable.py

@@ -3,7 +3,7 @@ from __future__ import annotations
 from dataclasses import dataclass, field
 from dataclasses import dataclass, field
 from typing import Any, Awaitable, Callable, ClassVar, Dict, Generic, List, Optional, Tuple, TypeVar, Union, cast
 from typing import Any, Awaitable, Callable, ClassVar, Dict, Generic, List, Optional, Tuple, TypeVar, Union, cast
 
 
-from typing_extensions import ParamSpec, Self
+from typing_extensions import Concatenate, ParamSpec, Self
 
 
 from .. import background_tasks, core
 from .. import background_tasks, core
 from ..client import Client
 from ..client import Client
@@ -11,6 +11,7 @@ from ..dataclasses import KWONLY_SLOTS
 from ..element import Element
 from ..element import Element
 from ..helpers import is_coroutine_function
 from ..helpers import is_coroutine_function
 
 
+_S = TypeVar('_S')
 _T = TypeVar('_T')
 _T = TypeVar('_T')
 _P = ParamSpec('_P')
 _P = ParamSpec('_P')
 
 
@@ -127,6 +128,17 @@ class refreshable(Generic[_P, _T]):
         ]
         ]
 
 
 
 
+class refreshable_method(Generic[_S, _P, _T], refreshable[_P, _T]):
+
+    def __init__(self, func: Callable[Concatenate[_S, _P], Union[_T, Awaitable[_T]]]) -> None:
+        """Refreshable UI methods
+
+        The `@ui.refreshable_method` decorator allows you to create methods that have a `refresh` method.
+        This method will automatically delete all elements created by the function and recreate them.
+        """
+        super().__init__(func)  # type: ignore
+
+
 def state(value: Any) -> Tuple[Any, Callable[[Any], None]]:
 def state(value: Any) -> Tuple[Any, Callable[[Any], None]]:
     """Create a state variable that automatically updates its refreshable UI container.
     """Create a state variable that automatically updates its refreshable UI container.
 
 

+ 2 - 1
nicegui/ui.py

@@ -91,6 +91,7 @@ __all__ = [
     'open',
     'open',
     'page_title',
     'page_title',
     'refreshable',
     'refreshable',
+    'refreshable_method',
     'state',
     'state',
     'update',
     'update',
     'page',
     'page',
@@ -196,7 +197,7 @@ from .functions.notify import notify
 from .functions.on import on
 from .functions.on import on
 from .functions.open import open  # pylint: disable=redefined-builtin
 from .functions.open import open  # pylint: disable=redefined-builtin
 from .functions.page_title import page_title
 from .functions.page_title import page_title
-from .functions.refreshable import refreshable, state
+from .functions.refreshable import refreshable, refreshable_method, state
 from .functions.update import update
 from .functions.update import update
 from .page import page
 from .page import page
 from .page_layout import Drawer as drawer
 from .page_layout import Drawer as drawer

+ 2 - 2
tests/test_refreshable.py

@@ -71,7 +71,7 @@ def test_multiple_targets(screen: Screen) -> None:
             self.name = name
             self.name = name
             self.state = 1
             self.state = 1
 
 
-        @ui.refreshable
+        @ui.refreshable_method
         def create_ui(self) -> None:
         def create_ui(self) -> None:
             nonlocal count
             nonlocal count
             count += 1
             count += 1
@@ -165,7 +165,7 @@ def test_refresh_with_function_reference(screen: Screen):
             self.count = 0
             self.count = 0
             self.ui()
             self.ui()
 
 
-        @ui.refreshable
+        @ui.refreshable_method
         def ui(self):
         def ui(self):
             ui.notify(f'Refreshing {self.name} ({self.count})')
             ui.notify(f'Refreshing {self.name} ({self.count})')
             self.count += 1
             self.count += 1