binding dataclass page
This commit is contained in:
@@ -202,4 +202,5 @@ Return:
|
||||
## References
|
||||
|
||||
- Architecture and integration details: [NiceGUI architecture reference](./references/architecture.md)
|
||||
- Dataclass binding deep dive: [Bindable dataclasses in NiceGUI](./references/binding-dataclasses.md)
|
||||
- Source documentation links: [NiceGUI source documentation](./references/source-documentation.md)
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# Binding Dataclasses Deep Dive
|
||||
|
||||
This reference explains how to model state with NiceGUI bindable dataclasses and how to avoid common update and performance pitfalls.
|
||||
|
||||
## Primary Sources
|
||||
|
||||
- NiceGUI binding docs: [Binding properties](https://www.nicegui.io/documentation/section_binding_properties)
|
||||
- Python dataclass docs: [dataclasses module](https://docs.python.org/3/library/dataclasses.html)
|
||||
- Data class design rationale: [PEP 557](https://peps.python.org/pep-0557/)
|
||||
|
||||
## What bindable_dataclass changes
|
||||
|
||||
`@binding.bindable_dataclass` extends standard dataclasses by turning fields into bindable properties so UI bindings can propagate immediately when a field is assigned.
|
||||
|
||||
Baseline pattern:
|
||||
|
||||
```python
|
||||
from nicegui import binding, ui
|
||||
|
||||
@binding.bindable_dataclass
|
||||
class Profile:
|
||||
name: str = 'Ada'
|
||||
age: int = 37
|
||||
|
||||
profile = Profile()
|
||||
|
||||
ui.input('Name').bind_value(profile, 'name')
|
||||
ui.number('Age', min=0).bind_value(profile, 'age')
|
||||
ui.label().bind_text_from(profile, 'name', backward=lambda n: f'User: {n}')
|
||||
```
|
||||
|
||||
## Propagation model and performance
|
||||
|
||||
NiceGUI distinguishes between two link types:
|
||||
|
||||
- Bindable properties: efficient, event-like propagation on assignment.
|
||||
- Active links: polled in a refresh loop (default every 0.1s).
|
||||
|
||||
Practical implications:
|
||||
|
||||
- Prefer bindable dataclasses for frequently updated form state.
|
||||
- Keep transform functions pure and side-effect free.
|
||||
- If many active links exist, tune `binding_refresh_interval` in `ui.run(...)` carefully.
|
||||
|
||||
## Dataclass modeling rules that matter for binding
|
||||
|
||||
- Use `field(default_factory=...)` for mutable defaults.
|
||||
- Avoid `frozen=True` for models that should be edited from UI controls.
|
||||
- Use `slots=True` only when you have confirmed compatibility with your inheritance and extension needs.
|
||||
- Keep UI-editable fields explicit and typed.
|
||||
|
||||
Example with safe mutable defaults:
|
||||
|
||||
```python
|
||||
from dataclasses import field
|
||||
from nicegui import binding
|
||||
|
||||
@binding.bindable_dataclass
|
||||
class Filters:
|
||||
query: str = ''
|
||||
tags: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
## Nested structures and binding paths
|
||||
|
||||
NiceGUI supports nested key paths via tuples for nested data (for example dictionaries and nested structures).
|
||||
|
||||
```python
|
||||
from nicegui import ui
|
||||
|
||||
data = {'user': {'name': 'Ada'}}
|
||||
|
||||
ui.input('Name').bind_value(data, ('user', 'name'))
|
||||
ui.label().bind_text_from(data, ('user', 'name'))
|
||||
```
|
||||
|
||||
When using nested dataclasses, keep updates explicit and predictable at the field level.
|
||||
|
||||
## Strictness and refactor safety
|
||||
|
||||
Binding can warn when attributes do not exist.
|
||||
|
||||
- Object attributes are checked by default.
|
||||
- Dictionary keys are not checked by default.
|
||||
- Use `strict=True` when you want missing-key warnings for dict-backed state.
|
||||
|
||||
```python
|
||||
from nicegui import app, ui
|
||||
|
||||
ui.input().bind_value(app.storage.user, 'display_name', strict=True)
|
||||
```
|
||||
|
||||
## Common pitfalls and safer alternatives
|
||||
|
||||
- Pitfall: mutating nested mutable values in place and expecting immediate UI sync.
|
||||
- Safer alternative: assign back to the bound field after updates so change propagation is explicit.
|
||||
|
||||
- Pitfall: heavy transform functions in bindings.
|
||||
- Safer alternative: keep transformations cheap and deterministic; move heavy work to event handlers.
|
||||
|
||||
- Pitfall: one model shared across unrelated pages or users.
|
||||
- Safer alternative: scope model instances to page/client/user context as needed.
|
||||
|
||||
## Version notes to remember
|
||||
|
||||
- `bindable_dataclass` added in NiceGUI 2.11.0.
|
||||
- Binding `strict` behavior documented as added in NiceGUI 3.0.0.
|
||||
- Tuple paths for nested properties documented as added in NiceGUI 3.10.0.
|
||||
- Depth-first binding propagation update documented in NiceGUI 2.16.0.
|
||||
|
||||
Verify behavior against the NiceGUI version pinned in your project before relying on version-specific semantics.
|
||||
|
||||
## Quick checklist
|
||||
|
||||
- Choose bindable dataclasses for interactive form-like state.
|
||||
- Use `default_factory` for mutable fields.
|
||||
- Keep transform functions pure.
|
||||
- Use strict mode intentionally.
|
||||
- Re-check version notes before migration work.
|
||||
@@ -26,8 +26,15 @@ Use these links for framework-specific details.
|
||||
|
||||
!!! info "NiceGUI sources"
|
||||
- [Pages, routing, and FastAPI integration](https://www.nicegui.io/documentation/section_pages_routing)
|
||||
- [Binding properties and bindable dataclass](https://www.nicegui.io/documentation/section_binding_properties)
|
||||
- [Security best practices](https://www.nicegui.io/documentation/section_security)
|
||||
|
||||
## Python Dataclasses
|
||||
|
||||
!!! info "Python sources"
|
||||
- [dataclasses module reference](https://docs.python.org/3/library/dataclasses.html)
|
||||
- [PEP 557: Data Classes](https://peps.python.org/pep-0557/)
|
||||
|
||||
## LangGraph
|
||||
|
||||
!!! info "LangGraph sources"
|
||||
|
||||
Reference in New Issue
Block a user