Как передавать состояние между виджетами, расположенных в разных routes
Написал приложение, которое должно:
- Отображать список Employee из базы данных;
- Добавлять новых Employee в базу данных(в другом окне).
Я понимаю, как изменять состояния виджетов, если произошли изменения в пределах ЭТОГО же окна. Но что, если изменения произошли во втором окне, а отобразить эти изменения требуется в первом? Код ниже решал бы мою проблему... Только если его расположить выше моих routes, он перестает отрабатывать как надо.
FutureBuilder<List<Employee>>(
future: DBProvider.db.getEmployees(),
builder: (BuildContext context, AsyncSnapshot<List<Employee>> snapshot)
{ return ... ; }
)
Свой код не выкладываю, так как мой вопрос сейчас больше на понимание. Какие есть способы для решения конкретно моей задачи?
Ответы (2 шт):
Автор решения: Дмитрий Окладной
→ Ссылка
Вот коротенький пример того как решить данную проблему
// Создаешь контроллер потока
StreamController<List<Employee>> gStreamController = StreamController();
// Далее идут какие-то твои классы в которых ты получаешь данные из базы данных
class DBProvider {
static DbProv db;
}
class DbProv {
getEmployees() {
//
Employee someEmployee1 = Employee();
Employee someEmployee2 = Employee();
Employee someEmployee3 = Employee();
Employee someEmployee4 = Employee();
// Допустим тут ты получил свои данные (список [Employee] элементов)
List<Employee> data = [
someEmployee1,
someEmployee2,
someEmployee3,
someEmployee4,
];
//!!! И вот самое интересное!!!))) Именно в этом местте отправляешь весь свой список данных на поток [gStreamController], который будет перехвачен в потоковом строителе
// в этом месте [stream: gStreamController.stream,]
gStreamController.add(data);
}
}
class Employee {}
class Test extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<List<Employee>>(
//!!! Место перехвата данных которые были отправлены в строке [gStreamController.add(data);]
stream: gStreamController.stream,
builder: (context, AsyncSnapshot<List<Employee>> snapshot) {
List<Employee> data = snapshot.data;
// Из [data] уже строить то отображение которое думал
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text('${data[index]}');
},
);
});
}
}
Автор решения: Дмитрий Окладной
→ Ссылка
// Создаешь просто переменную контроллера потока
StreamController<List<Employee>> gStreamController;
// Далее идут какие-то твои классы в которых ты получаешь данные из базы данных
class DBProvider {
static DbProv db;
}
class DbProv {
getEmployees() {
//
Employee someEmployee1 = Employee();
Employee someEmployee2 = Employee();
Employee someEmployee3 = Employee();
Employee someEmployee4 = Employee();
// Допустим тут ты получил свои данные (список [Employee] элементов)
List<Employee> data = [
someEmployee1,
someEmployee2,
someEmployee3,
someEmployee4,
];
//!!! И вот самое интересное!!!))) Именно в этом местте отправляешь весь свой список данных на поток [gStreamController], который будет перехвачен в потоковом строителе
// в этом месте [stream: gStreamController.stream,]
gStreamController.add(data);
}
}
class Employee {}
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
// перезаписываем внутреннюю функцию [didChangeDependencies()] в [StatefulWidget]
@override
void didChangeDependencies() async{
// Тут (на всякий случай проверяем закрытие контролера)
await gStreamController?.close();
// Тут его создаем.
gStreamController = StreamController();
super.didChangeDependencies();
}
// перезаписываем внутреннюю функцию [dispose()] в [StatefulWidget]
@override
void dispose() {
// Тут закрываем поток (когда происходит закрытие вашего виджета)
gStreamController?.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<List<Employee>>(
//!!! Место перехвата данных которые были отправлены в строке [gStreamController.add(data);]
stream: gStreamController.stream,
builder: (context, AsyncSnapshot<List<Employee>> snapshot) {
List<Employee> data = snapshot.data;
// Из [data] уже строить то отображение которое думал
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text('${data[index]}');
},
);
});
}
}