一尘不染

团体,flutter和导航

flutter

因此,像大多数人一样,我是Bloc的新手,挥舞着飞镖,将我的头缠住。我已经用Google搜索过,浏览了这里的帖子,但还没有找到真正的答案。

所以这是关于用团块和颤动进行导航的。以登录为例。因此,有一个登录页面,后面有一个集团,有时有人按下按钮进行登录。

因此,我们可以在集团中调用一个函数进行验证。我认为这违反严格的方法,但我看到有人这样做。但是,如果登录成功,您如何导航到下一个屏幕?您不应该在集团中导航吗?

但是,如果该登录页面正在使用StreamBuilder更改状态,那么您也不能在构建器中添加导航,可以吗?您无法返回导航,而是返回小部件。

您可以在initstate中导航,但是在initstate中可以有一个流构建器来侦听整个组中的状态变化吗?

现在这有点令人困惑,但是我很坚持,因为这 应该 是前进的方向…

谢谢保罗


阅读 225

收藏
2020-08-13

共1个答案

一尘不染

为了让集团成为神话
前进方向正确的方式进行:对于处理状态不完美的方式。每种状态管理体系结构都比其他的解决方案要好。总会有一些折衷,因此在决定架构时要意识到这一点很重要。

通常, 良好的体系结构是可行的
:它具有可伸缩性和可扩展性,而只需要最小的开销。由于人们对实用性的观点各不相同,因此架构始终会涉及各种观点,因此请仔细考虑以下内容,因为我将就如何在您的应用程序中采用BLoC提出自己的看法。

BLoC是Flutter中非常有前途的状态管理方法,因为它具有一个标志性成分:流。它们允许将UI与业务逻辑分离,并且与Flutter-
ish方法配合使用,可以很好地重建过时的整个小部件子树。因此,很自然,往返于BLoC的每个通信都应使用流,对吗?

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

好吧,有点。

要记住的重要一点是, 状态管理体系结构是达到目的的一种手段
。您不应该只是为了做到这一点而做事,还要保持开放的态度并仔细评估每种选择的利弊。我们将BLoC与UI分开的原因是,BLoC不需要关心UI的结构-
它仅提供一些不错的简单流,而数据发生的一切都是UI的责任。

但是,尽管流已被证明是从BLoC到UI传输信息的一种绝妙方式,但它们却在另一个方向上增加了不必要的开销:流被设计为传输连续的数据流(甚至是名称),但是大多数时间,UI仅需要触发BLoC中的单个事件。因此,有时您会看到某些Stream<void>或类似的恶意解决方案¹,只是为了遵循严格的BLoC-
y处理方式。

另外,如果我们根据来自BLoC的流推送新路由,则BLoC基本上可以控制UI流程-但是我们试图避免的是拥有直接控制UI和业务逻辑的代码!

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

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

在这里,BLoC返回Streams为“实时”数据,并且Futures作为方法调用的答案。

让我们来看看如何为您的示例工作:

  • BLoC可以提供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.
    }

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

  • BLoC实际上只是执行了应做的工作–处理业务逻辑(在这种情况下,请登录用户)。
  • UI只关心两件事:
    • 显示来自Stream和的用户数据
    • 通过在BLoC中触发用户操作并根据结果执行UI操作来对用户操作做出反应。²

最后,我想指出的是,这只是一种可能的解决方案,它通过尝试在复杂应用程序中处理状态的不同方式随着时间而发展。重要的是要了解有关状态管理如何工作的不同观点,因此我鼓励您深入研究该主题,也许是通过观看Google
I / O的“ Flutter中的实用状态管理”会议。

编辑 :刚刚在Brian
Egan的体系结构样本中
发现了此体系结构,该示例称为“简单BLoC”。如果您想了解不同的体系结构,我真的建议您看一下该仓库。


¹尝试为BLoC动作提供多个参数时,它变得更加难看-因为您需要定义一个包装器类才能将其传递给Stream。

²我 确实
承认启动应用程序时它会变得有些丑陋:您需要某种启动屏幕,该启动屏幕仅检查BLoC的流,并根据用户是否登录将用户重定向到适当的屏幕。发生该规则异常是因为用户执行了一项操作(启动应用程序),但是Flutter框架不允许我们直接参与(据我所知,至少不是很优雅)。

2020-08-13