router.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. from typing import Awaitable, Callable, Dict, Union
  2. from nicegui import background_tasks, ui
  3. from nicegui.dependencies import register_component
  4. register_component('router_frame', __file__, 'router_frame.js')
  5. class Router():
  6. def __init__(self) -> None:
  7. self.routes: Dict[str, Callable] = {}
  8. self.content: ui.element = None
  9. def add(self, path: str):
  10. def decorator(func: Callable):
  11. self.routes[path] = func
  12. return func
  13. return decorator
  14. def open(self, target: Union[Callable, str]):
  15. if isinstance(target, str):
  16. path = target
  17. builder = self.routes[target]
  18. else:
  19. path = {v: k for k, v in self.routes.items()}[target]
  20. builder = target
  21. async def build():
  22. with self.content:
  23. await ui.run_javascript(f'history.pushState({{page: "{path}"}}, "", "{path}")', respond=False)
  24. result = builder()
  25. if isinstance(result, Awaitable):
  26. await result
  27. self.content.clear()
  28. background_tasks.create(build())
  29. def frame(self) -> ui.element:
  30. self.content = ui.element('router_frame').on('open', lambda msg: self.open(msg['args']))
  31. return self.content