所以,和大多数人一样,我是新加入阵营的,我会飞起来,dart 飞奔,我会把脑袋绕起来.我在谷歌上搜索过,浏览过这里的帖子,但没有找到任何答案.

所以这是关于用阻塞和Flutter 导航的.以登录为例.因此,有一个登录页面,后面有一个块,在某个点上,有人按下一个按钮进行登录.

因此,我们可以在块中调用执行验证的函数.我认为这与严格的做法背道而驰,但我看到人们在这样做.但是,如果登录成功,如何导航到下一个屏幕呢?你不应该在一个区块里航行吗?

但是,如果登录页面使用StreamBuilder更改状态,那么您也不能在构建器中添加导航,不是吗?你不能返回导航,你只能返回小部件.

initstate是一个你可以导航的地方,但是你能在initstate中有一个流生成器来监听集团中的状态变化吗?

现在这一切都有点令人困惑,但我会坚持不懈,因为这是supposed美元的前进方向……

谢谢 保罗

推荐答案

要让欧盟向前the步的神话就此消失:没有完美的方式来处理国家问题.

通常,good architecture is practical:它是可伸缩和可扩展的,并且只需要很少的开销. 因为人们对实用性的看法不同,架构总是会有不同的看法,所以请对以下内容持保留态度,因为我将就如何为您的应用程序采用BLOC阐述我的个人观点.

BLOC是一种非常有前途的Flutter 状态管理方法,因为它有一个标志性的元素:STREAMS. 它们允许将UI与业务逻辑解耦,并且它们很好地使用了在部件子树过时后重新构建整个部件子树的快速方法. 因此,自然地,进出集团的每一次通信都应该使用流,对吗?

+----+  Stream   +------+
| UI | --------> | BLoC |
|    | <-------- |      |
+----+   Stream  +------+

嗯,算是吧.

重要的是要记住state management architecture is a means to an end点;你不应该只是为了它而做事,而应该保持开放的心态,仔细判断每个选项的利弊. 我们将块与UI分开的原因是,块不需要关心UI是如何构造的-它只提供一些很好的简单流,数据发生什么都是UI的责任.

但是,尽管流已被证明是将信息从块传输到UI的一种奇妙方式,但它们在另一个方向上增加了不必要的开销: STREAMS被设计为传输连续的数据流(甚至在名称中也是如此),但是大多数情况下,UI只需要触发块中的单个事件.这就是为什么有时你会看到一些Stream<void>或类似的陈词滥调的解决方案,仅仅是为了坚持严格的集团做事方式.

此外,如果我们基于来自块的流推送新的路由,块基本上会控制UI流-但是拥有直接控制UI和业务逻辑的代码正是我们试图阻止的事情!

这就是为什么一些开发人员(包括我)只是打破了完全基于流的解决方案,而采用了一种从UI触发块中事件的自定义方式. 就我个人而言,我只是使用方法调用(通常返回Future)来触发块的事件:

+----+   method calls    +------+
| UI | ----------------> | BLoC |
|    | <---------------- |      |
+----+   Stream, Future  +------+

在这里,对于"活动"的数据,BLoC返回Stream秒,对于方法调用返回Future秒.

让我们看看你的例子是如何实现的:

  • 该区块可以提供用户是否登录的Stream<bool>,甚至Stream<Account>,其中Account包含用户的帐户信息.
  • BLoC还可以提供一个异步Future<void> signIn(String username, String password)方法,如果登录成功或抛出错误,该方法将不返回任何内容.
  • UI可以自己处理输入管理,并在按下登录按钮后触发如下内容:
try {
  setState(() => _isLoading = true); // This could display a loading spinner of sorts.
  await Bloc.of(context).signIn(_usernameController.text, _passwordController.text);
  Navigator.of(context).pushReplacement(...); // Push logged in screen.
} catch (e) {
  setState(() => _isLoading = false);
  // TODO: Display the error on the screen.
}

这样,您就可以很好地分离关注点:

  • 该块实际上只是做它应该做的事情-处理业务逻辑(在本例中,让用户登录).
  • UI只关心两件事:

最后,我想指出的是,这只是一种可能的解决方案,它是通过try 在复杂应用程序中处理状态的不同方式而随着时间的推移而发展起来的. 了解关于状态管理如何工作的不同观点很重要,因此我鼓励您在挖洞上更深入地探讨这个话题,也许可以通过观看来自Google I/O的第"Pragmatic State Management in Flutter"次会议来实现.

EDIT:刚在Brian Egan's architecture samples年发现了这种 struct ,它被称为"简单集团".如果你想了解不同的体系 struct ,我真的建议你看看回购协议.


?当试图向一个块操作提供多个参数时,它会变得更加难看-因为这样您就需要定义一个包装类来将其传递给Stream.

²我承认,启动应用程序时会有点难看:你需要某种启动屏幕,只需判断集团的流,并根据用户是否登录将其重定向到适当的屏幕.这一规则的例外是因为用户执行了一个操作——启动应用程序——但Flutter 框架不允许我们直接参与其中(据我所知,至少不优雅).

Flutter相关问答推荐

Flutter:带有表单的SpeechToTextprovider

ListTile未正确显示在flutter中

Flutter:sqflite DB

修复容器`Text`和容器表单之间的重叠

壁炉有序在Flutter

Flutter 中的多页表现

如何删除使用isscllable时出现的左边距?

在背景图像上排列定位徽标

任务';:app:check DebugDuplicateClasss';的Ffltter Share_plus抛出执行失败

Flutter 数独网格

如何将带有参数的函数传递给FIFTH中的自定义小部件

未处理的异常:第1行第5列出现错误:无效的媒体类型:应为/&;.从API获取数据时在Flutter中

创建仅定义导出的文件是否有意义?

TextField 中的富文本并获取 RenderParagraph

Flutter http 请求获取 null

要禁用按钮上的通知声音,请点击Flutter

如何从另一个页面访问 Firebase 值?

对话框打开时如何使背景模糊?

如何在 tabBar 中的选项卡之间制作垂直线?

如何使用我拥有的 .jks 文件签署我的应用程序