Я теряю потоковые данные при переходе на другой экран - PullRequest
0 голосов
/ 15 апреля 2019

Я новичок в Дарт / Флаттер, и после "посещения" курса Удеми все идет хорошо.До сих пор; -)

Как и в примере приложения в курсе 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», содержащий два дополнительных блока для разделения различных данных.Например:

class AppBloc {  
  //Variables holding the continous state
  Locale appLocale;

  final UserBloc userBloc;
  final GroupsBloc groupsBlock;

В моем приложении у меня есть «GroupSearchScreen» только с одним полем ввода, где вы можете ввести фрагмент имени группы.При нажатии кнопки выполняется вызов REST API и возвращается список имен групп.

Как и в примере приложения, я также помещаю данные в поток.

В примере приложения данныеизвлечение и размещение в потоке выполняется в блоке itselve.На следующей строке создается Экран, который использует данные.Как это:

//Collecting data and putting it in the stream
storiesBloc.fetchTopIds();
//Creating a screen ths shows a list
return NewsList();

В моем случае, однако, есть два основных различия:

  1. После сбора данных в GroupSearchScreen я вызываю / создаю GroupsListScreen, гдесписок групп должен отображаться с использованием обычной маршрутизации!Например:

    // Добавить данные в поток («changeGroupList» предоставляет функцию добавления потока!) AppBloc.groupsBlock.changeGroupList (groups);// Вызов / создание экрана для отображения списка групп Navigator.pushNamed (context, '/ groups_list');

  2. В созданном GroupsListScreen я получаю блок.Например:

    Сборка виджета (контекст) {final 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 у меня есть оператор print.Следовательно, я вижу, что GroupsListScreen - это сборка zwice.Это должно быть нормально, но может ли это быть причиной отсутствия данных в потоке?Прослушивается ли поток дважды?

Widget buildList(AppBloc appBloc) {
  return StreamBuilder(
    stream: appBloc.groupsBlock.groups,

Я пытался объяснить свою проблему таким образом, не предоставляя тонны кода.Но я не знаю, достаточно ли этого, чтобы дать подсказку, где я могу продолжить поиск ...

Обновление 16.04.2019 - РЕШЕНИЕ:

Я создаю свое первое приложение, используя другое приложение, показанное накурс Удеми ...

Самое важное различие между "его" приложением и my - это то, что он создает виджет, который прослушивает поток, а затем добавляет данные в поток.

Я добавляюданные в поток, а затем перейдите к виджету, который показывает данные.

К сожалению, я использовал RX-Dart "PublishSubject".Если вы прослушаете это, вы получите все данные, помещенные в поток, начиная с того времени, когда вы начали слушать!

RX-Dart "BehaviorSubject", однако, также даст вам последние данные, просто перед тем, как вы начали слушать.

Вот то поведение, которое мне было нужно здесь:

  1. Поместить данные в поток

  2. Создать виджет и начать слушать

Я могу посоветовать всем новичкам Флаттера прочитать оба эти очень хороших учебных пособия:

https://medium.com/flutter-community/reactive-programming-streams-bloc-6f0d2bd2d248

https://www.didierboelens.com/2018/12/reactive-programming---streams---bloc---practical-use-cases/

В первом из них оба упомянутых потока объяснены очень хорошо.

...