#flutter #dart #state #bloc #flutter-bloc
#flutter #dart #состояние #блок #flutter-bloc
Вопрос:
У меня есть blockbuilder, который обрабатывает создание виджетов в зависимости от полученного состояния для моей страницы панели мониторинга.
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();
}
Ответ №1:
Вместо того, чтобы пытаться изменить состояние другой страницы (немного нет-нет, когда речь идет об управлении состоянием), воспользуйтесь тем фактом, что push
метод навигатора возвращает future, который завершается при открытии этой страницы, и в качестве бонуса значение 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(...);
}
}
Примечание: это работает так же хорошо и для именованных маршрутов.
Комментарии:
1. Похоже, это именно то, что мне было нужно. Я попробую завтра вечером и приму ваш ответ, как только он заработает. Спасибо!
2. Работает абсолютно идеально. Еще раз спасибо.