所以像大多数人一样,我是新的集团和扑和 dart 和 Package 我的头周围。我在谷歌上搜索过,看过这里的帖子,但没有找到任何答案。
所以这是关于有块和 Flutter 的导航。以Login为例。所以有一个登录页面,后面有一个块,在某个时候有人按下一个按钮登录。
所以我们可以调用块中的一个函数来进行验证。我认为这是违反严格的做法,但我看到人们这样做。但是,如果登录成功,您如何导航到下一个屏幕?你不应该在一个区域航行吗?
但是如果登录页面使用StreamBuilder来更改状态,那么您也不能在构建器中添加导航,可以吗?你不能返回导航,你返回的是小部件。
initstate是您可以导航的地方,但是您可以在initstate中使用流构建器来侦听块中的状态更改吗?
现在一切都有点混乱,但我坚持下去,因为这是 * 应该 * 是前进的道路…
谢谢Paul
6条答案
按热度按时间wnvonmuf1#
为了让BLoC成为 * 前进的道路的神话:处理状态没有完美的方法。每个状态管理体系结构都比其他体系结构更好地解决了一些问题;总有一些权衡,在决定架构时,意识到它们是很重要的。
一般来说,好的架构是实用的:它具有可伸缩性和可扩展性,同时只需要最小的开销。由于人们对实用性的看法不同,架构总是涉及到意见,所以请对以下内容持保留态度,因为我将阐述我个人对如何在您的应用程序中采用BLoC的看法。
BLoC是Flutter中状态管理的一种非常有前途的方法,因为它有一个标志性的成分:它们允许将UI与业务逻辑解耦,并且它们与Flutter式的方法配合良好,即在过时时重建整个小部件子树。所以很自然地,来自和去往BLoC的每个通信都应该使用流,对吗?
算是吧
需要记住的重要一点是状态管理架构是达到目的的手段;你不应该只是为了做某事而做某事,而是要保持开放的心态,仔细评估每个选择的利弊。我们将BLoC与UI分开的原因是BLoC不需要关心UI是如何结构化的-它只是提供一些简单的流,数据发生的任何事情都是UI的责任。
但是,虽然流已被证明是将信息从BLoC传输到UI的绝佳方式,但它们在另一个方向上增加了不必要的开销:流被设计为传输连续的数据流(它甚至在名称中),但大多数时候,UI只需要触发BLoC中的单个事件。这就是为什么有时你会看到一些
Stream<void>
或类似的黑客解决方案¹,只是为了坚持严格的BLoC-y做事方式。此外,如果我们根据来自BLoC的流推送新路由,BLoC基本上会控制UI流--但是直接控制UI和业务逻辑的代码正是我们试图阻止的!
这就是为什么一些开发人员(包括我)只是打破完全基于流的解决方案,并采用一种自定义的方式从UI触发BLoC中的事件。就我个人而言,我只是使用方法调用(通常返回
Future
s)来触发BLoC的事件:这里,BLoC返回
Stream
s作为“实时”数据,返回Future
s作为方法调用的应答。让我们看看如何为您的示例工作:
Stream<bool>
,甚至Stream<Account>
,其中Account
包含用户的帐户信息。Future<void> signIn(String username, String password)
方法,如果登录成功,则不返回任何内容,否则抛出错误。通过这种方式,您可以很好地分离关注点:
Stream
s和最后,我想指出的是,这只是一种可能的解决方案,它是通过在复杂的应用程序中尝试不同的处理状态的方法而逐渐发展起来的。了解关于状态管理如何工作的不同观点是很重要的,因此我鼓励您深入研究这个主题,也许可以通过观看Google I/O的"Pragmatic State Management in Flutter"会议。
编辑:刚刚在Brian Egan's architecture samples中找到了这个架构,它被称为“Simple BLoC”。如果你想了解不同的架构,我真的建议你看看repo。
¹当试图为BLoC动作提供多个参数时,它会变得更加丑陋-因为这样你就需要定义一个 Package 器类来将其传递给Stream。
²我承认在启动应用程序时它会变得有点丑陋:您需要某种启动屏幕,它只是检查BLoC的流,并根据用户是否登录将其重定向到适当的屏幕。这个规则的例外是因为用户执行了一个动作--启动应用程序--但是Flutter框架不允许我们直接挂钩到这个动作(至少据我所知不是很优雅)。
7xllpg7q2#
BlocListener
是您可能需要的小部件。如果状态更改为(例如)LoginSuccess
,则块侦听器可以调用通常的Navigate.of(context)
。你可以找到一个example ofBlocListener
in action near the bottom of this page。另一种选择是向事件传递回调。
u5rb5r593#
正如felangel在Github下面的issue中提到的,我们可以使用BlocListner来实现这个目的。
ejk8hzay4#
首先:如果没有业务逻辑,则不需要转到YourBloc类。
但是有时候一些用户的活动需要在Bloc类中执行一些逻辑,然后Bloc类必须决定下一步做什么:只需重新构建小部件或显示对话框甚至导航到下一个路由。在这种情况下,您必须向UI发送一些State来完成操作。然后另一个问题出现了:当Bloc发送State显示吐司时,我应该如何处理小部件?
这是这个故事的主要问题。
很多答案和文章都推荐使用flutter_block。这个库有BlocBuilder和BlocListener。有了这些类,你可以解决一些问题,但不是100%。
在我的例子中,我使用了BlocConsumer,它管理BlocBuilder和BlocListener,并提供了管理状态的出色方法。
来自文档:
如您所见,使用BlocConsumer可以过滤状态:你可以很容易地定义状态来重建小部件和状态来显示一些弹出窗口或导航到下一个屏幕。
am46iovg5#
完全同意**@Volodymyr Yatsykiv的关于使用BlocConsumerWidget的回答,但只是添加一个实现管理导航的示例,以防成功登录并重建小部件**当有请求时可能会有所帮助,所以我在下面添加。
}
myss37ts6#
完整的
Flutter BLOC
示例