навигация по шаблону блока флаттера назад приводит к плохому состоянию - PullRequest
0 голосов
/ 24 октября 2018

У меня есть проблема / вопрос, касающийся блока блока с флаттером.В настоящее время я запускаю свое приложение, как это

class _MyAppState extends State<MyApp> {

@override
  Widget build(BuildContext context) {        
    return BlocProvider(
        bloc: MyBloc(),
        child: MaterialApp(
          title: "MyApp",
          home: MyHomePage(),    
          routes: {
            '/homePage': (context) => MyHomePage(),
            '/otherPage': (context) => OtherPage(),
            '/otherPage2': (context) => OtherPage2(),
            ...
          },
        ));

, чтобы я мог получить / получить доступ к myBloc, как

myBloc = BlocProvider.of(context) as MyBloc;

, и данные, представленные в состоянии, как

BlocBuilder<MyBlocEvent, MyObject>(
    bloc: myBloc,
    builder: (BuildContext context, MyObject myObject) {         
     ....
     var t = myObject.data;
     ....
     myBloc.onFirstEvent();
     ...
 }; 

везде, где мне это нужно.

MyBloc реализован так:

abstract clas MyBlocEvent {}
class FirstEvent extends MyBlocEvent {}
class SecondEvent extends MyBlocEvent {}

class MyBloc extends Bloc<MyBlocEvent , MyObject>

void onFirstEvent()
{
  dispatch(FirstEvent());
}

void onSecondEvent()
{
  dispatch(SecondEvent());
}

@override
Stream<MyObject> mapEventToState( MyObject state, MyBlocEvent event) async* {
if (event is FirstEvent) {
    state.data = "test1";
}
else if (event is SecondEvent) {
    state.otherData = 5;
}
    yield state;
}

Проблема, с которой я столкнулся, заключается в том, что, как только я изменяю значения состояния и вызываю

Navigator.pop(context)

Чтобы вернуться в текущий стек, я ничего не могу изменить, это состояние больше, потому что основной поток, кажется, закрыт.Сбой с сообщением:

Было сгенерировано другое исключение: Плохое состояние: невозможно добавить новые события после вызова close "

Теперь это происходит только после того, как я вызову pop. Еслия только нажимаю на новые экраны, я могу без проблем менять данные о состоянии без проблем.

Я делаю что-то не так в отношении навигации здесь или есть что-то еще, что я не уловил относительно флаттера или самого шаблона блока?

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Плохое состояние: невозможно добавить новые события после вызова close

Эта ошибка означает, что вы звоните add на StreamController после , вызвав close:

 var controller = StreamController<int>();
 controller.close();
 controller.add(42); // Bad state: Cannot add new events after calling close

Вероятно, это связано с тем, что вы называете close внутри метода dispose "неправильным" виджетом.

Хорошее эмпирическое правило: никогда не располагайте / не закрывайте объект вне виджета, который его создал.Это гарантирует, что вы не можете использовать объект, уже утилизированный.

0 голосов
/ 08 января 2019

Надеюсь, это поможет в вашей отладке.

Навигация в приложении зависит от дизайна ваших виджетов.

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

Всякий раз, когда я перехожу на другую страницу, я выскакиваю текущий виджет и перехожу к следующему виджету.

Следующий виджет без состояния объявляет блок, тогда в ваших последующих виджетах без состояния должны содержаться вызовы типа MyBloc.dispatch(event(param1: value1, param2: value2));

В MyBloc вам нужно установить фабрику вашего состояния, содержащую конечные значения;

@override
Stream<MyObject> mapEventToState( MyObject state, MyBlocEvent event) async* {
if (event is FirstEvent) {
    // set it in the state, so this code is omitted
    // state.data = "test1";
    // add this
    yield state.sampleState([], "test1");
}
else if (event is SecondEvent) {
    // state.otherData = 5;
    yield state.sampleState([], 5);
} else {
    yield state.sampleState([], null);
}

MyObjectState необходимо настроить следующим образом:

class MyObjectState {
  final List<Bar> bars;
  final String Foo;

  const MyObjectState(
      {this.bars,
      this.foo,
  });

  factory MyObjectState.sampleState(List<Bar> barList, String value1) {
    return MyObjectState(bars: barList, foo: message);
  }
}

, чтобывиджет без сохранения состояния может использовать блок, подобный этому MyBloc.currentState.sampleState.foo

Вы можете попробовать запустить флаттер проекта Феликса Ангелова. Пример потока входа в систему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...