binding dataclass page

This commit is contained in:
John Lancaster
2026-06-23 19:46:35 -05:00
parent a6ccc14917
commit 45a1e56d1c
3 changed files with 127 additions and 0 deletions
+1
View File
@@ -202,4 +202,5 @@ Return:
## References ## References
- Architecture and integration details: [NiceGUI architecture reference](./references/architecture.md) - 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) - 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" !!! info "NiceGUI sources"
- [Pages, routing, and FastAPI integration](https://www.nicegui.io/documentation/section_pages_routing) - [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) - [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 ## LangGraph
!!! info "LangGraph sources" !!! info "LangGraph sources"