我是Dart / Flutter的新手,在“参加” Udemy比赛后, 一切进展顺利。 直到现在;-)
就像Udemy课程中的示例应用程序一样,我正在使用BLOC模式。
赞:
class App extends StatelessWidget {
Widget build(context) {
return AppBlocProvider(
child: MaterialApp(
(请参阅稍后使用“ AppBlocProvider”以获取“ AppBloc”)
该应用程序以及所有屏幕都是StatelessWidget的。
AppBlocProvider扩展了InheritedWidget。 像这样:
class AppBlocProvider extends InheritedWidget {
final AppBloc bloc;
AppBlocProvider({Key key, Widget child})
: bloc = AppBloc(),
super(key: key, child: child);
bool updateShouldNotify(_) => true;
static AppBloc of(BuildContext context) {
return (context.inheritFromWidgetOfExactType(AppBlocProvider) as AppBlocProvider).bloc;
}
}
AppBlocProvider提供了一个“ AppBloc”,其中包含另外两个bloc,用于将不同的数据稍微分开。 像这样:
class AppBloc {
//Variables holding the continous state
Locale appLocale;
final UserBloc userBloc;
final GroupsBloc groupsBlock;
在我的应用程序中,我有一个“ GroupSearchScreen”,其中只有一个输入字段,您可以在其中输入 组名的一部分。点击按钮时,将执行REST API调用,并返回组名列表。
就像在示例应用程序中一样,我也将数据放在流中。
在示例应用程序中,将数据提取并将其放入流中是在其自身中完成的。 在下一行,创建了使用数据的屏幕。 像这样:
//Collecting data and putting it in the stream
storiesBloc.fetchTopIds();
//Creating a screen ths shows a list
return NewsList();
但是,就我而言,有两个主要区别:
在GroupSearchScreen中收集数据后,我调用/创建GroupsListScreen,在其中应显示组列表, 使用常规路由! 像这样:
///向流添加数据(“ changeGroupList”赋予流的添加功能!) appBloc.groupsBlock.changeGroupList(groups); //调用/创建屏幕以显示组列表 Navigator.pushNamed(上下文,'/ groups_list');
在创建的GroupsListScreen中,我获取了块。 像这样:
小部件构建(上下文){ 最终的AppBloc appBloc = AppBlocProvider.of(context);
这些是路线:
Route routes(RouteSettings settings) {
switch (settings.name) {
case '/':
return createLoginScreen();
case '/search_group':
return createSearchGroupScreen();
case '/groups_list':
return createGroupsListScreen();
default:
return null;
}
}//routes
“ / groups_list”指向此功能:
Route createSearchGroupScreen() {
return MaterialPageRoute(
builder: (context) {
//Do we need a DashboardScreen BLOC?
//final storiesBloc = StoriesProvider.of(context);
//storiesBloc.fetchTopIds();
return GroupSearchScreen();
}
);
}
如您所见,“ AppBlocProvider”仅使用一次。 (我也遇到了这个问题;-)
现在是问题所在:
当GroupsListScreen开始呈现列表时,流/快照没有数据!
(请参阅“ if(!snapshot.hasData)”)
Widget buildList(AppBloc appBloc) {
return StreamBuilder(
stream: appBloc.groupsBlock.groups,
builder: (context, AsyncSnapshot<List<Map<String, dynamic>>>snapshot) {
if (!snapshot.hasData) {
为了测试整块中的所有数据是否丢失,我尝试不将数据直接放入流中, 而是在成员变量中(在blloc中!)
在GroupSearchScreen中,我将json数据放入集团的成员变量中。
现在,就在GroupsListScreen开始呈现列表之前,我将数据(json)从整体中取出, 把我放到溪流中,直到现在仍然驻留在集团中,一切正常! 小睡有数据...
类似(在GroupsListScreen中):
//Add data to Stream
appBloc.groupsBlock.changeGroupList(appBloc.groupsBlock.groupSearchResult);
为什么地球上的流从“ GroupSearchScreen”到“ GroupsListScreen”的途中“丢失”了其数据 什么时候普通成员变量不是?两者都居住在同一个集团中!
在GroupsListScreen的build方法开始时,我有一条打印语句。 因此,我可以看到,GroupsListScreen是构建zwice。 那应该很正常,但是那可能是在流中找不到数据的原因吗? 流是否收听了两次?
Widget buildList(AppBloc appBloc) {
return StreamBuilder(
stream: appBloc.groupsBlock.groups,
我试图用这种方式解释我的问题,没有提供大量的代码。 但是我不知道它是否足以提示我可以继续搜索...
更新16.04.2019-解决方案:
我使用在Udemy课程中看到的另一个应用程序构建了我的第一个应用程序...
“ his”应用程序与“我的”应用程序之间最重要的区别在于,他创建了侦听流的Widget,然后将数据添加到流中。
我将数据添加到流中,然后导航到显示数据的小部件。
不幸的是,我使用了RX-Dart“ PublishSubject”。如果您收听那首歌,那么从您开始收听的那一刻起,您就将所有数据放入流中!
但是,RX镖“ BehaviorSubject”也将为您提供最后的数据,只是在您开始收听之前。
多数民众赞成在这里我需要的行为:
将数据放入流
创建窗口小部件并开始收听
我可以招募Flutter的所有新手来阅读这两个很好的教程:
https://medium.com/flutter-community/reactive-programming-streams-bloc-6f0d2bd2d248
https://www.didierboelens.com/2018/12/reactive-programming---streams---bloc---practical-use-cases/
在第一个中,对上述两个流进行了很好的解释。