nicegui table updates

This commit is contained in:
John Lancaster
2026-08-30 01:01:50 -05:00
parent 3e2fc0ef25
commit 65669a2100
7 changed files with 274 additions and 108 deletions
@@ -66,7 +66,42 @@ After registration, propagation follows these rules:
Since NiceGUI `2.16.0`, this depth-first walk updates each affected node once per pass. Transform functions must not depend on call count or traversal order.
### Bindable Properties Versus Active Links
## Authoritative Models And Projections
A bindable dataclass can own canonical page state while plain dictionaries or component properties act as serializable projections. Use a one-way binding from each model field to its projection when browser rendering requires a different container shape:
```python
from nicegui import binding
projection = {"name": profile.name}
binding.bind_to(
profile,
"name",
projection,
"name",
other_strict=True,
)
```
Assigning `profile.name` then propagates immediately to `projection["name"]`. The projection is transport state, not a second business model; application code should locate and mutate the owning dataclass rather than treating browser-visible dictionaries as authoritative. This distinction is especially useful when one client-side scoped template renders many records and therefore cannot bind to one fixed Python object. The [editable-table pattern](./tables.md) applies it to one row dataclass and one QTable payload per stable row identity.
Browser-originated values still require Python validation before model assignment. Keep editable fields explicit, normalize into domain types, verify permissions and record existence, and only then assign the bindable field. For the client event path that carries such proposals, see [server-authoritative edit proposals](./component-mechanics.md#server-authoritative-edit-proposals).
### Persistence And Rollback
Treat a dataframe, service, or repository as the persistence boundary around the canonical bindable model:
1. validate and normalize the proposed value
2. remember the previous model value
3. assign the normalized value so bound projections update
4. persist the model through the owning adapter, service, or repository
5. if persistence fails, restore the previous model value before reporting or re-raising the error
6. refresh the affected component from the resulting projection on both acceptance and rejection
For asynchronous persistence, await the transaction and refresh only after it commits or rolls back. Catch expected validation, conflict, and persistence exceptions separately so the interface can report actionable failures without hiding programming errors. Component-specific refresh APIs and identity rules remain the responsibility of the consuming pattern; for QTable, see [persistence and row refresh](./tables.md#persistence-and-row-refresh).
## Bindable Properties Versus Active Links
| Source | Change detection | Update timing |
| --- | --- | --- |