Bladeren bron

introduce emitEvent and ui.on

Falko Schindler 1 jaar geleden
bovenliggende
commit
f4432a4836

+ 1 - 2
nicegui/events.py

@@ -392,8 +392,7 @@ def handle_event(handler: Optional[Callable[..., Any]], arguments: EventArgument
         if isinstance(arguments, UiEventArguments):
             if arguments.sender.is_ignoring_events:
                 return
-            assert arguments.sender.parent_slot is not None
-            parent_slot = arguments.sender.parent_slot
+            parent_slot = arguments.sender.parent_slot or arguments.sender.client.layout.default_slot
         else:
             parent_slot = nullcontext()
 

+ 23 - 0
nicegui/functions/on.py

@@ -0,0 +1,23 @@
+from typing import Any, Callable, Optional, Sequence, Union
+
+from .. import context
+
+
+def on(type: str,  # pylint: disable=redefined-builtin
+       handler: Optional[Callable[..., Any]] = None,
+       args: Union[None, Sequence[str], Sequence[Optional[Sequence[str]]]] = None, *,
+       throttle: float = 0.0,
+       leading_events: bool = True,
+       trailing_events: bool = True,
+       ):
+    """Subscribe to a global event.
+
+    :param type: name of the event
+    :param handler: callback that is called upon occurrence of the event
+    :param args: arguments included in the event message sent to the event handler (default: `None` meaning all)
+    :param throttle: minimum time (in seconds) between event occurrences (default: 0.0)
+    :param leading_events: whether to trigger the event handler immediately upon the first event occurrence (default: `True`)
+    :param trailing_events: whether to trigger the event handler after the last event occurrence (default: `True`)
+    """
+    context.get_client().layout.on(type, handler, args,
+                                   throttle=throttle, leading_events=leading_events, trailing_events=trailing_events)

+ 3 - 0
nicegui/templates/index.html

@@ -54,6 +54,9 @@
           return element.$refs.qRef[method_name](...args);
         }
       }
+      function emitEvent(event_name, ...args) {
+        getElement(0).$emit(event_name, ...args);
+      }
     </script>
     <script type="module">
       const True = true;

+ 2 - 0
nicegui/ui.py

@@ -97,6 +97,7 @@ __all__ = [
     'footer',
     'header',
     'left_drawer',
+    'on',
     'page_sticky',
     'right_drawer',
     'run',
@@ -190,6 +191,7 @@ from .functions.download import download
 from .functions.html import add_body_html, add_head_html
 from .functions.javascript import run_javascript
 from .functions.notify import notify
+from .functions.on import on
 from .functions.open import open  # pylint: disable=redefined-builtin
 from .functions.page_title import page_title
 from .functions.refreshable import refreshable, state

+ 18 - 16
website/documentation/content/generic_events_documentation.py

@@ -99,26 +99,28 @@ def modifiers() -> None:
 
 
 @doc.demo('Custom events', '''
-    It is fairly easy to emit custom events from JavaScript which can be listened to with `element.on(...)`.
+    It is fairly easy to emit custom events from JavaScript with `emitEvent(...)` which can be listened to with `ui.on(...)`.
     This can be useful if you want to call Python code when something happens in JavaScript.
     In this example we are listening to the `visibilitychange` event of the browser tab.
 ''')
 async def custom_events() -> None:
-    tabwatch = ui.checkbox('Watch browser tab re-entering') \
-        .on('tabvisible', lambda: ui.notify('Welcome back!') if tabwatch.value else None, args=[])
-    ui.add_head_html(f'''
-        <script>
-        document.addEventListener('visibilitychange', () => {{
-            if (document.visibilityState === 'visible')
-                getElement({tabwatch.id}).$emit('tabvisible');
-        }});
-        </script>
-    ''')
+    tabwatch = ui.checkbox('Watch browser tab re-entering')
+    ui.on('tabvisible', lambda: ui.notify('Welcome back!') if tabwatch.value else None)
+    # ui.add_head_html('''
+    #     <script>
+    #     document.addEventListener('visibilitychange', () => {
+    #         if (document.visibilityState === 'visible') {
+    #             emitEvent('tabvisible');
+    #         }
+    #     });
+    #     </script>
+    # ''')
     # END OF DEMO
     await context.get_client().connected()
-    ui.run_javascript(f'''
-        document.addEventListener('visibilitychange', () => {{
-            if (document.visibilityState === 'visible')
-                getElement({tabwatch.id}).$emit('tabvisible');
-        }});
+    ui.run_javascript('''
+        document.addEventListener('visibilitychange', () => {
+            if (document.visibilityState === 'visible') {
+                emitEvent('tabvisible');
+            }
+        });
     ''')