[英]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.