跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

状态管理

如果你来自 React/Flutter/Compose,请做好准备迎接最大的差异:没有响应式数据绑定。没有会自动重绘的 useState/Observable/setState()。这里的模型是命令式 + 显式失效 —— 其中的“为什么”在 状态与数据流中说明。

该模式

状态存在于你自己对象(一个 ViewModel/服务)的普通字段中。当它变化时,你更新 widget并调用 repaint() —— 如果来自其他线程,则放在 Component.onUI(...) 内。

class HomeVM {
   List<Cliente> clientes = new ArrayList<>();
}

public class TelaHome extends Window {
   private final HomeVM vm = new HomeVM();
   private ListView<Cliente> lista;

   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_FILL, lista = new ListView<>());
      carregar();
   }

   private void carregar() {
      new Thread(() -> {
         List<Cliente> dados = repositorio.buscarTudo();   // 繁重工作,后台 thread
         Component.onUI(() -> {                             // 返回 paint thread
            vm.clientes = dados;
            lista.setItems(dados);                          // 更新 widget
            Component.repaint();                            // 请求新的一帧
         });
      }).start();
   }
}

临时状态 vs. 应用状态

类型 存在于何处 能否在导航后存活?
屏幕临时状态 Window 的字段 否 —— 离开屏幕即消失
应用状态 一个共享的单例/服务 是 —— 在各屏幕间持久保留

按作用域选择:搜索的过滤条件是临时的;已登录的用户是应用级的。

最佳实践

  • 每个屏幕一个 ViewModel 集中状态和逻辑;Window 只负责连接 UI ↔ VM。
  • 屏幕间共享的状态 → 服务/单例,而非散落各处的静态字段。
  • 从后台线程操作 widget 之前,务必先用 onUI(...) 回到 UI。

常见错误

  • 期望修改模型就能自动更新 UI —— 不会更新;请调用 setX(...) + repaint()。
  • 把应用状态存在 Window 的字段里(导航时会丢失)。

另见

这个页面有帮助吗?