Блок - Можно ли получить состояния для предыдущей страницы в стеке навигации?

У меня есть BlocBuilder, который обрабатывает строительные виджеты в зависимости от полученного состояния для моей страницы панели инструментов.

body: BlocBuilder<DashboardBloc, DashboardState>(
        builder: (context, state) {
          print(state);
          if (state is DashboardInitial) {
            return loadingList();
          } else if (state is DashboardEmpty) {
            return emptyList();
          } else if (state is DashboardLoaded) {
            return loadedList(context, state);
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => AddPage()));
        },

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

class AddPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    TextEditingController titleController = TextEditingController();
    TextEditingController descriptionController = TextEditingController();
    return Scaffold(
      appBar: AppBar(title: Text('Add')),
      body: Container(
        padding: EdgeInsets.all(10),
        child: Column(
          children: [
            TextField(
              controller: titleController,
            ),
            TextField(
              controller: descriptionController,
            ),
            RaisedButton(onPressed: () {
              BlocProvider.of<DashboardBloc>(context)
                  .add(DashboardWorryAdded('title', 'description'));
            }),
          ],
        ),
      ),
    );
  }
}

Следуя коду с использованием точек останова, я могу видеть, что мое состояние передается в функции mapeventtostate, однако моя панель никогда не перестраивается с новыми значениями.

Вот код для моего Блока, событий и состояний. Моей первой мыслью было бы, что Equatable обнаруживал то же самое возвращаемое состояние, но после удаления Equatable моя проблема все еще сохраняется.

 @override
  Stream<DashboardState> mapEventToState(
    DashboardEvent event,
  ) async* {
    if (event is DashboardWorryAdded) {
      yield* _mapDashboardWorryAddedToState(event);
    } else if (event is DashboardLoading) {
      yield* _mapDashboardLoadingToState(event);
    } else if (event is AppStarted) {
      yield* _mapAppStartedToState(event);
    }
  }

  Stream<DashboardState> _mapAppStartedToState(AppStarted event) async* {
    List<Worry> _wList = await repo.getAllWorries();
    if (_wList.length != 0) {
      yield DashboardLoaded(worryList: _wList);
    } else {
      yield DashboardEmpty();
    }
  }

  Stream<DashboardState> _mapDashboardLoadingToState(
      DashboardLoading event) async* {
    List<Worry> _wList = await repo.getAllWorries();
    if (_wList != 0) {
      yield DashboardLoaded(worryList: _wList);
    } else {
      yield DashboardEmpty();
    }
  }

  Stream<DashboardState> _mapDashboardWorryAddedToState(
      DashboardWorryAdded event) async* {
    await repo.addWorry(event.title, event.description);
    List<Worry> worryList = List<Worry>();
    worryList = await repo.getAllWorries();
    yield DashboardLoaded(worryList: worryList);
  }
}
@immutable
abstract class DashboardEvent {}

class DashboardLoading extends DashboardEvent {
  DashboardLoading();
}

class DashboardWorryAdded extends DashboardEvent {
  final String title, description;

  DashboardWorryAdded(this.title, this.description);
}

class AppStarted extends DashboardEvent {
  AppStarted();
}
@immutable
abstract class DashboardState {}

class DashboardInitial extends DashboardState {
  DashboardInitial();
}

class DashboardLoaded extends DashboardState {
  final List<Worry> worryList;

  DashboardLoaded({this.worryList});
}

class DashboardEmpty extends DashboardState {
  DashboardEmpty();
}

person Sam    schedule 13.10.2020    source источник


Ответы (1)


Вместо того, чтобы пытаться изменить состояние другой страницы (что-то вроде «нет-нет», когда речь идет об управлении состоянием), воспользуйтесь преимуществом того факта, что метод push навигатора возвращает будущее, которое завершается, когда эта страница открывается, и в качестве бонуса , значение future будет включать значение, которое было присвоено методу pop на другой странице. Итак, теперь вы можете сделать что-то вроде этого:

class DashboardBloc {
  ...

  void showAddPage() async {
    // Do this to retrieve the value passed to the add page's call to `pop`
    final value = await Navigator.of(context).push(...);

    // Do this if the add page doesn't return a value in `pop`
    await Navigator.of(context).push(...);

    // Either way, you can now refresh your state in response to 
    // the add page popping
    emit(...);
  }
}

Примечание. Это также работает и для именованных маршрутов.

person Abion47    schedule 13.10.2020
comment
Похоже, это именно то, что я искал. Я попробую завтра вечером и приму твой ответ, как только он заработает. Благодарю вас! - person Sam; 14.10.2020
comment
Работает абсолютно отлично. Спасибо еще раз. - person Sam; 14.10.2020