将存储库实例 "alive" 与 bloc 保持在一起
keeping repository instance "alive" with bloc
我仍在使用我的第一个基于 bloc 的应用程序,添加功能。之前,我使用 bloc class 存储了一些特定于页面的数据,对于最后一个功能,我现在将大部分变量移到了它的存储库中。我已经担心调用存储库的实例会丢失,后来证明是真的。
是否有适当、简单的方法使实例持久化?
我知道继承的小部件,但是,我还没有想出如何实现这个,不幸的是,我的 question 围绕这个问题仍然没有得到答复。如果有人能指出我的方向,那就太好了!
总的来说,我的想法是让 api 处理本地文件和在线数据、包含经常重复使用的数据(会话数据、呈现的数据等)的存储库和 bloc 中的辅助变量。因此,当 UI 请求数据时,bloc 会询问存储库 return 一个存储在变量中的值,或者从 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;
}
}
此行正在创建和初始化您的用户存储库:
final UserRepository userRepository = UserRepository(); // <===== userRepository initialized
然而,这一行没有传递那个存储库,它正在创建一个新存储库,忽略你刚刚初始化的那个:
runApp(MyApp(userRepository: UserRepository()));
我想你是想使用你已有的变量:
runApp(MyApp(userRepository: userRepository));
我仍在使用我的第一个基于 bloc 的应用程序,添加功能。之前,我使用 bloc class 存储了一些特定于页面的数据,对于最后一个功能,我现在将大部分变量移到了它的存储库中。我已经担心调用存储库的实例会丢失,后来证明是真的。
是否有适当、简单的方法使实例持久化?
我知道继承的小部件,但是,我还没有想出如何实现这个,不幸的是,我的 question 围绕这个问题仍然没有得到答复。如果有人能指出我的方向,那就太好了!
总的来说,我的想法是让 api 处理本地文件和在线数据、包含经常重复使用的数据(会话数据、呈现的数据等)的存储库和 bloc 中的辅助变量。因此,当 UI 请求数据时,bloc 会询问存储库 return 一个存储在变量中的值,或者从 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;
}
}
此行正在创建和初始化您的用户存储库:
final UserRepository userRepository = UserRepository(); // <===== userRepository initialized
然而,这一行没有传递那个存储库,它正在创建一个新存储库,忽略你刚刚初始化的那个:
runApp(MyApp(userRepository: UserRepository()));
我想你是想使用你已有的变量:
runApp(MyApp(userRepository: userRepository));