[英]Global dependency on flutter_bloc
我在使用flutter_bloc在 Flutter 上实现应用程序时遇到问题。 我理解了核心概念,但我发现了一个没有示例或指南的“边缘案例”(至少我能找到):
(我将简化问题)我有一个名为AuthBloc
的集团来管理App
。 如果 state 是NotAuthenticated
则应用程序应该显示LoginScreen
但如果是Authenticated
应用程序应该显示HomeScreen
。 在HomeScreen
内,我有 4 个块,其中每个块都有其状态和事件,但它们都依赖于不同的Repositories
以从 API 获取一些数据。
所有Repositories
都需要一个令牌来发出 API 请求。 第一个问题来了。 如何从所有存储库中获取令牌? 如果我使用UserRepository
来存储令牌,我需要将它作为依赖项传递给每个存储库(可能有效,但我认为这不是正确的方法)。 那么,管理这个问题的正确方法是什么?
第二个问题是:
如果我能以某种方式在所有存储库查询中获得令牌,那么当令牌被撤销时会发生什么? 该应用程序应返回到LoginScreen
,为此我需要通过事件(例如InvalidTokenEvent
)通知AuthBloc
。 并且AuthBloc
应该将其 state 更改为NotAuthenticated
,这将重建LoginScreen
。 但问题是:如何从其他集团或存储库通知AuthBloc
? 我的第一个想法是通过依赖注入:我可以将 AuthBloc 传递给构造函数中的每个其他块,因此当存储库请求返回令牌过期时, XBloc
可以调用AuthBloc.add(InvalidTokenEvent)
。 但同样,如果我有很多集团,我需要在每个集团中都这样做。 那么,这样做的正确方法是什么?
感谢您的任何帮助!
所有存储库都需要一个令牌来发出 API 请求。 第一个问题来了。 如何从所有存储库中获取令牌? 如果我使用 UserRepository 来存储令牌,我需要将它作为依赖项传递给每个存储库(可能有效,但我认为这不是正确的方法)。 那么,管理这个问题的正确方法是什么?
这不是一个不好的做法(将其添加为依赖项),但为了使其更容易,您可以使用 getIt 和可注入库来获得适当的依赖项注入解决方案。
另一种方法是,在您的网络层添加一个拦截器,也就是说,在发出 http 请求之前,您可以拦截您的请求,在该层的请求中添加令牌并继续请求阶段。
大多数网络库都有请求和响应拦截器,如下所示:
但这不是 Bloc 库的问题。
如果我能以某种方式在所有存储库查询中获得令牌,那么当令牌被撤销时会发生什么?
您可以添加另一个响应拦截器来检测您是否有未经身份验证的响应,以便您可以注销用户。
使用getIt ,您可以从全局依赖容器和注销用户中收集该块。
要回答您的第一个问题:
您的存储库不应处理 API 身份验证。 这应该是存储库层下数据层的工作。
我建议拥有一个 http 客户端实例,然后将此实例提供给所有存储库。 这样,您的客户端可以有一个拦截器来处理将保存的令牌添加到您的所有请求。 因此,您的存储库可能如下所示:
class OrderRepository {
const OrderRepository(this.httpClient);
final HttpClient httpClient;
}
然后 rest 将像初始化您的 httpclient 然后将其传递到您的存储库一样简单,您可以使用RepositoryProvider
或MultiRepositoryProvider
将其提供给您的应用程序和块。 然后对您的存储库和 bloc 执行相同的操作,将您的存储库传递给 blocproviders 内的 bloc。
要回答您的第二个问题:
如果可以在 http 客户端层处理身份验证并将令牌传递给所有请求,那么应该取消身份验证和撤销令牌。 因此,要在您的身份验证 state 中反映这一点,您的 AuthRepository 应该听您的 http 客户端,同样您的 AuthBloc 应该听您的 AuthRepository。 您可以通过在您的 http 客户端和您的 AuthRepository 中公开您的身份验证状态的 stream 来做到这一点,该 AuthRepository 会在您的 auth bloc 中被监听。
所以它看起来像这样:http 客户端收到 401 错误,因此它从存储中删除令牌,然后将未经身份验证的状态添加到 stream。 然后,此 stream 在 auth 存储库中公开,然后在 auth bloc 中有一个 stream 订阅,该订阅侦听身份验证状态以发出未经身份验证的 Z9ED39E2EA931586B6A985A6942EF7。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.