团体,颤动和导航 [英] Bloc, Flutter and Navigation

查看:77
本文介绍了团体,颤动和导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So like most, i'm new to Bloc and flutter and dart and wrapping my head around. I've googled, looked through the posts here but haven't found really any answers.

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

So this is about navigation with bloc and flutter. Take the example of a Login. So there is a login page with a bloc behind it and at some point someone presses a button to login.

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

So we can call a function in the bloc that does the validation. I think this is against the strict approach but i see people doing this. But then if login is successful how do you navigate to the next screen? You're not supposed to navigate in a bloc?

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

But if that login page is using a StreamBuilder to change state then you cannot add a navigate in a builder either can you? You can't return navigation, you return widgets.

可以在initstate中导航某个位置,但是可以在initstate中放置一个流生成器,以侦听bloc中状态的变化吗?

The initstate is somewhere you could navigate, but can you have a stream builder in an initstate that listens for state changes in the bloc?

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

It's all a little confusing right now but i'm persevering as this is supposed to be the way forward...

谢谢 保罗

推荐答案

要弄清BLoC的神话就是 前进的道路:没有完美的状态处理方法. 每个状态管理体系结构都比其他的解决方案要好.总会有权衡取舍,在决定架构时要意识到这一点很重要.

To get the myth of BLoC being the way forward right out of the way: There is no perfect way for handling state. Every state management architecture solves some problems better than others; there are always trade-offs and it's important to be aware of them when deciding on an architecture.

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

Generally, good architecture is practical: It's scalable and extensible while only requiring minimal overhead. Because people's views on practicability differ, architecture always involves opinion, so take the following with a grain of salt as I will lay out my personal view on how to adopt BLoC for your app.

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

BLoC is a very promising approach for state management in Flutter because of one signature ingredient: streams. They allow for decoupling the UI from the business logic and they play well with the Flutter-ish approach of rebuilding entire widget subtrees once they're outdated. So naturally, every communication from and to the BLoC should use streams, right?

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

好吧,

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

The important thing to remember is that state management architecture is a means to an end; you shouldn't just do stuff for the sake of it but keep an open mind and carefully evaluate the pros and cons of each option. The reason we separate the BLoC from the UI is that the BLoC doesn't need to care about how the UI is structured – it just provides some nice simple streams and whatever happens with the data is the UI's responsibility.

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

But while streams have proven to be a fantastic way of transporting information from the BLoC to the UI, they add unnecessary overhead in the other direction: Streams were designed to transport continuous streams of data (it's even in the name), but most of the time, the UI simply needs to trigger single events in the BLoC. That's why sometimes you see some Stream<void>s or similarly hacky solutions¹, just to adhere to the strictly BLoC-y way of doing things.

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

Also, if we would push new routes based on the stream from the BLoC, the BLoC would basically control the UI flow – but having code that directly controls both the UI and the business logic is the exact thing we tried to prevent!

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

That's why some developers (including me) just break with the entirely stream-based solution and adopt a custom way of triggering events in the BLoC from the UI. Personally, I simply use method calls (that usually return Futures) to trigger the BLoC's events:

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

在这里,BLoC会为实时数据返回Stream,并为方法调用的答案返回Future.

Here, the BLoC returns Streams for data that is "live" and Futures as answers to method calls.

让我们看看如何解决您的示例:

Let's see how that could work out for your example:

  • BLoC可以提供用户是否已登录的Stream<bool>,甚至是Stream<Account>,其中Account包含用户的帐户信息.
  • BLoC还可以提供一个异步Future<void> signIn(String username, String password)方法,如果登录成功,该方法将不返回任何内容,否则将引发错误.
  • UI可以自行处理输入管理,并在按下登录按钮后触发类似以下的内容:
  • The BLoC could provide a Stream<bool> of whether the user is signed in, or even a Stream<Account>, where Account contains the user's account information.
  • The BLoC could also provide an asynchronous Future<void> signIn(String username, String password) method that returns nothing if the login was successful or throws an error otherwise.
  • The UI could handle the input management on its own and trigger something like the following once the login button is pressed:
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.
}

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

This way, you get a nice separation of concerns:

  • BLoC实际上只是按照预期的方式工作–处理业务逻辑(在这种情况下,请登录用户).
  • UI只关心两件事:
    • 显示来自Stream s和
    • 的用户数据
    • 通过在BLoC中触发用户操作并根据结果执行UI操作来对用户操作做出反应.²
    • The BLoC really just does what it's supposed to do – handle the business logic (in this case, signing the user in).
    • The UI just cares about two things:
      • Displaying user data from Streams and
      • reacting to user actions by triggering them in the BLoC and performing UI actions based on the result.²

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

      Finally, I want to point out that this is only one possible solution that evolved over time by trying different ways of handling state in a complex app. It's important to get to know different points of view on how state management could work so I encourage you to dig deeper into that topic, perhaps by watching the "Pragmatic State Management in Flutter" session from Google I/O.

      编辑:刚刚在 Brian Egan的架构示例中找到了该架构它称为简单BLoC".如果您想了解不同的体系结构,我真的建议您查看回购协议.

      EDIT: Just found this architecture in Brian Egan's architecture samples, where it's called "Simple BLoC". If you want to get to know different architectures, I really recommend having a look at the repo.

      ¹尝试为BLoC动作提供多个参数时,它变得更加丑陋–因为这时您需要定义一个包装器类,以便将其传递给Stream.

      ¹ It gets even uglier when trying to provide multiple arguments to a BLoC action – because then you'd need to define a wrapper class just to pass that to the Stream.

      ²我承认启动应用程序时它有点难看:您将需要某种启动屏幕,该启动屏幕仅检查BLoC的流并将用户重定向到基于是否登录.发生该规则的异常是因为用户执行了一个操作(启动应用程序),但是Flutter框架不允许我们直接参与(据我所知,至少不是很优雅).

      ² I do admit it gets a little bit ugly when starting the app: You'll need some sort of splash screen that just checks the BLoC's stream and redirects the user to the appropriate screen based on whether he/she signed in or not. That exception to the rule occurs because the user performed an action – starting the app – but the Flutter framework doesn't directly allow us to hook into that (at least not elegantly, as far as I know).

      这篇关于团体,颤动和导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆