【问题标题】:keeping repository instance "alive" with bloc使用 bloc 保持存储库实例“活动”
【发布时间】:2021-02-23 11:07:35
【问题描述】:

我仍在使用我的第一个基于 bloc 的应用程序,正在添加功能。之前,我使用 bloc 类存储了一些特定于页面的数据,对于最后一个功能,我现在将大多数变量移到了它的存储库中。我已经担心调用存储库的实例会丢失,后来证明是真的。

是否有适当、简单的方法使实例持久化?

我知道继承的小部件,但是,我还没有弄清楚如何实现这一点,不幸的是,我的 question 对此仍未得到答复。如果有人能指出我的方向,那就太好了!

一般来说,我的想法是让 api 处理本地文件和在线数据、包含经常重用数据(会话数据、呈现数据等)的存储库和块内的辅助变量。因此,当 UI 请求数据时,bloc 会询问存储库,该存储库将返回存储在变量中的值或从 api 请求值。

这就是结构的基本外观(希望我没有错过任何重要的东西)

void main() async {
  final UserRepository userRepository = UserRepository(); // <===== userRepository initialized
  runApp(MyApp(userRepository: UserRepository()));
}

class MyApp extends StatelessWidget {
  MyApp({Key key, this.userRepository}) : assert(userRepository != null), super(key: key);
  final UserRepository userRepository;

  @override
  Widget build(BuildContext context) {
    return BlocProvider<UserBloc>(  <====== userBloc injection to top of widget tree 
      create: (_) => UserBloc(userRepository: userRepository)..add(AppStarted()),
      child: App(),
    );
  }
}
// =================================================== APP WITH ROUTES
class App extends StatelessWidget {
  App({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      routes: {
        '/': (_) => HomePage(),
        'feature 1': (_) => HomePage(),
      },
    );
  }
}
// =================================================== LANDING PAGE WITH MAIN MENU
class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>  { 
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('MathUup'),
      ),
      child: SafeArea(
        child: CupertinoButton(
          child: Text('Feature 1',
              onPressed: () => Navigator.pushNamed(context, 'feature 1'),
  ),)));
}}     
// =================================================== BLOC
class UserBloc extends Bloc<UserEvent, UserState> {
  UserBloc({this.userRepository}) : super(AppInitial());
  final UserRepository userRepository;
  ...
    
      final user = await userRepository.getActiveUserData(userId);
      final lastSessionData = await userRepository.getLastSession(userId);
  ...
}
// =================================================== REPOSITORY
class UserRepository {
  UserRepository();
  final UserApiClient achievementsApiClient = UserApiClient();
  final SessionsApiClient sessionsApiClient = SessionsApiClient();
  UserSession activeUserSession;
  User activeUserData;
  
  
  Future<String> getLastUserId() async {
    final lastUserId = await sessionsApiClient.getLastUserId();
    return lastUserId;
  }
  Future<UserSession> getActiveUser() async {
    if (activeUserSession == null) {
      activeUserSession = await sessionsApiClient.getLastUser();
    }
    return activeUserSession;
  }
}
  
  

【问题讨论】:

  • 从技术上讲,您的存储库没有理由不能在应用程序的整个生命周期中保持相同的实例。现在,您是否以这种方式实施它是任何人的猜测。您将需要发布代码,并且可能需要发布特定错误或特定点,您的实例不是您期望的实例。
  • @nvoigt 谢谢,我添加了代码的重要部分。如果这留下了关于存储库实现的任何内容,请告诉我什么。复制整个代码可能会有点令人困惑以查找零碎
  • “我已经担心调用存储库的实例会丢失,后来证明这是真的。”你怎么知道?看起来不错。
  • 在启动时,我从本地文件加载数据并将其存储在存储库中的变量中。稍后,我想更新本地文件的数据。所以我再次调用存储库的一个函数(我在上面的示例中忘记复制它),将新数据添加到启动时加载的数据中并覆盖本地文件(json 结构使追加变得困难)。但是,在存储时,我发现存储库本地的变量现在为空。我检查了这个变量是在启动时填充的。

标签: flutter repository instance bloc


【解决方案1】:

这一行正在创建和初始化您的用户存储库:

final UserRepository userRepository = UserRepository(); // <===== userRepository initialized

但是,这一行没有通过该存储库,它正在创建一个 存储库,而忽略了您刚刚初始化的那个:

runApp(MyApp(userRepository: UserRepository()));

我认为你的意思是使用你已经拥有的变量:

runApp(MyApp(userRepository: userRepository));

【讨论】:

  • 非常好的观点。不幸的是,将其更改为 runApp(MyApp(userRepository: userRepository)) 仍然没有为我提供第二次调用的值。我追查了转发实例的方式,还没有找到另一个流程。所以我想,这一定是其他问题。但现在非常有助于排除问题的实例。
  • 您可以使用 IDE 的“查找用法”功能,看看您是否在某个时候将变量设置为 null。
  • 我的道歉。这确实是由不完整的测试数据引起的,导致一些奇怪的行为
猜你喜欢
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多