状态 API
State、ReactiveState、NavigationPath、Timer 和 Ref。
本页查 State、PersistentState、ReactiveState、NavigationPath、Timer、Ref、Prop、ObservableList、ObservableDict 的签名和边界。状态写法的完整解释见 状态管理。
#什么时候用
| 目标 | API |
|---|---|
| 普通表单、按钮、列表筛选 | State |
| 明确指定持久化状态 | PersistentState |
| 高频字段快路径 | ReactiveState |
| 程序化导航栈 | NavigationPath |
| 定时执行回调 | Timer |
| 保存不触发 UI 刷新的句柄 | Ref |
| 自定义实时属性 | Prop |
| 观察 list / dict 局部变更 | ObservableList / ObservableDict |
#State 示例
已复制
import appui
state = appui.State(count=0, saved=False)
save_count = appui.Ref(0)
def increment():
state.batch_update(count=state.count + 1, saved=False)
def save():
save_count.current += 1
state.saved = True
def body():
status = "Saved" if state.saved else "Editing"
return appui.NavigationStack(
appui.Form([
appui.Section("State", [
appui.LabeledContent("Count", value=str(state.count)),
appui.LabeledContent("Status", value=status),
appui.LabeledContent("Save count", value=str(save_count.current)),
appui.Button("+1", action=increment),
appui.Button("Save", action=save).button_style("bordered_prominent"),
])
]).navigation_title("State")
)
appui.run(body, state=state)
#Timer 示例
已复制
import appui
state = appui.State(seconds=0, running=False)
def tick():
if state.running:
state.seconds += 1
timer = appui.Timer(interval=1.0, repeats=True, action=tick)
def start():
state.running = True
timer.start()
def stop():
state.running = False
timer.stop()
def body():
return appui.NavigationStack(
appui.Form([
appui.Section("Timer", [
appui.LabeledContent("Seconds", value=str(state.seconds)),
appui.HStack([
appui.Button("Start", action=start).button_style("bordered_prominent"),
appui.Button("Stop", action=stop).button_style("bordered"),
], spacing=12),
])
]).navigation_title("Timer")
)
appui.run(body, state=state)
#状态签名
| API | 签名 | 分类 |
|---|---|---|
State | State(persist: Optional[Union[bool, Sequence[str]]] = None, persist_key: Optional[str] = None, transient: Optional[Sequence[str]] = None, debounce: float = 0.3, **kwargs: Any) | 公开类型 |
PersistentState | PersistentState(persist_key: Optional[str] = None, transient: Optional[Sequence[str]] = None, debounce: float = 0.3, **kwargs: Any) | 公开类型 |
ReactiveState | ReactiveState(**kwargs: Any) | 公开类型 |
NavigationPath | NavigationPath() | 公开类型 |
Timer | Timer(interval: float = 1.0, repeats: bool = True, action: Optional[Callable[[], None]] = None) | 公开类型 |
Ref | Ref(initial: Any = None) | 公开类型 |
Prop | Prop(prop_id: int, val_type: str = 'auto', default: Any = None, attr: Optional[str] = None) | 公开类型 |
ObservableList | ObservableList(data: Iterable[Any], notify: Callable[[], None]) | 公开类型 |
ObservableDict | ObservableDict(data: Mapping[Any, Any], notify: Callable[[], None]) | 公开类型 |
#主要方法
| API | 方法 | 签名 | 所属类型 |
|---|---|---|---|
State | batch_update | batch_update(**kwargs: Any) -> None | State |
State | to_dict | to_dict() -> Dict[str, Any] | State |
State | get | get(key: str, default: Any = None) -> Any | State |
State | flush_persisted | flush_persisted() -> bool | State |
State | clear_persisted | clear_persisted() -> bool | State |
ReactiveState | batch_update | batch_update(**kwargs: Any) -> None | ReactiveState |
ReactiveState | to_dict | to_dict() -> Dict[str, Any] | ReactiveState |
ReactiveState | get | get(key: str, default: Any = None) -> Any | ReactiveState |
ReactiveState | bind | bind(field_name: str, *, parse: Optional[Callable[[Any], Any]] = None, format: Optional[Callable[[Any], Any]] = None, validate: Optional[Callable[[Any], bool]] = None) -> Dict[str, Any] | ReactiveState |
ReactiveState | bind_handles | bind_handles(**bindings: int) -> None | ReactiveState |
NavigationPath | append | append(view_or_value: Union["View", str, int, Dict[str, Any]]) -> None | NavigationPath |
NavigationPath | pop | pop(count: int = 1) -> None | NavigationPath |
NavigationPath | pop_to_root | pop_to_root() -> None | NavigationPath |
NavigationPath | replace | replace(items: Sequence[Any]) -> None | NavigationPath |
Timer | start | start() -> None | Timer |
Timer | stop | stop() -> None | Timer |
#相邻 API 区别
| API | 用法边界 |
|---|---|
State vs ReactiveState | 普通页面用 State;高频字段才用 ReactiveState。 |
State(persist=...) vs PersistentState | 简单保存可用 State(persist=True);需要固定持久化 key 或更清晰语义时用 PersistentState。 |
Ref vs State | 需要显示到 UI 的值用 State;句柄、缓存、连接对象用 Ref。 |
ObservableList vs 重新赋值 | 频繁局部增删改可依赖可观察容器;简单场景重新赋值更直观。 |
Timer vs auto_refresh | 正式页面用 Timer;临时 demo 可用 auto_refresh。 |
NavigationPath vs NavigationLink | 固定行详情用 NavigationLink;程序化跳转用 NavigationPath。 |
#常见错误
| 错误 | 后果 | 修正 |
|---|---|---|
把 UI 要显示的值放进 Ref | 改值后界面不刷新 | 放进 State。 |
在 body() 里创建 Timer | 每次重建都可能新建计时器 | 模块级创建。 |
先创建没有回调的 Timer,再事后赋 action | 容易漏掉回调 | 初始化时传 action=tick。 |
| 连续写多个字段 | 产生多次重建和中间状态 | 使用 batch_update。 |
| 列表按过滤后的下标修改 | 搜索后操作错行 | 数据项保留稳定 id。 |