Я пишу флаттер приложение с базовыми функциями CRUD.
У меня есть экраны для списка элементов, подробного представления элемента и формы редактирования элемента.
Когда я касаюсь подробного экрана элемента из представления списка, данные отображаются правильно после первоначального создания элемента (с использованием отдельной формы).
Когда я нажимаю на форму редактирования на этом подробном экране, данные элемента передаются и предварительно заполняются в форме.
Когда я вносю изменения в данные этого элемента и сохраняю их, я возвращаюсь к подробному виду, но никакие подробности в этом представлении не менялись.
Однако, когда я поднимаюсь по дереву еще на один уровень, элемент в виде списка был обновлен.
Что мне здесь не хватает? Если родительский виджет с scopedModel имеет изменение состояния и уведомляется notifyListener()
, разве это не должно течь вниз по дереву виджетов?
Список:
class GiftListDisplayWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<GiftList>(
builder: (context, child, giftList) => ListView(
children: giftList.gifts.map((Gift gift) => GiftCard(gift)).toList(),
)
);
}
}
Подробный вид (некоторый код опущен для краткости)
class GiftDetailPage extends StatefulWidget {
final Gift gift;
GiftDetailPage(this.gift);
@override
_GiftDetailPageState createState() => _GiftDetailPageState();
}
class _GiftDetailPageState extends State<GiftDetailPage> {
Widget get giftProfile {
return ListView(
children: [titleSection, textSection, buttonSection, metadataSection],
);
}
Widget get titleSection {...}
Widget get textSection {...}
Widget get buttonSection {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FlatButton(...)
FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditGiftFormPage(widget.gift)));
},
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.edit, color: Colors.indigoAccent),
Container(
margin: const EdgeInsets.only(top: 8.0),
child: Text(
'EDIT',
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: Colors.indigoAccent,
),
),
),
],
),
),
FlatButton(...)
],
),
),
],
),
);
}
Widget get metadataSection {...}
_launchURL() async {...}
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<GiftList>(
builder: (context, child, giftList) => Scaffold(
appBar: AppBar(
title: Text('Gift Details'),
),
body: giftProfile,
),
);
}
}
А на экране редактирования формы:
class EditGiftFormPage extends StatefulWidget {
final Gift existingGift;
EditGiftFormPage(this.existingGift);
@override
_EditGiftFormPageState createState() => _EditGiftFormPageState();
}
class _EditGiftFormPageState extends State<EditGiftFormPage> {
TextEditingController nameController = TextEditingController();
TextEditingController statusController = TextEditingController();
TextEditingController descriptionController = TextEditingController();
GiftStatus selectedStatus;
Gift updatedGift;
@override
void initState() {
nameController.text = widget.existingGift.recipient;
selectedStatus = widget.existingGift.giftStatus;
descriptionController.text = widget.existingGift.recipient;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Gift'),
),
body: ScopedModelDescendant<GiftList>(
builder: (context, child, giftList) => Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 32.0,
),
child: Column(...),
),
),
),
);
}
save(GiftList giftList) {
if (nameController.text.isEmpty ||
descriptionController.text.isEmpty ||
selectedStatus == null) {
print('Make sure you have completed the form');
} else {
var newGift = Gift(
id: widget.existingGift.id,
recipient: nameController.text,
giftStatus: selectedStatus,
description: descriptionController.text,
imageUrl: 'https://picsum.photos/1080/608/?random');
giftList.update(newGift);
Navigator.of(context).pop();
}
}
}
С учетом того, что я уже написал, я ожидаю, что, поскольку все эти компоненты заботятся о модели giftList
, они должны прислушиваться к этой модели, и когда giftList.update
вызывается формой, они должны все пересборка.
В настоящее время только представление списка верхнего уровня отображает обновленные данные, состояние не передается через два дочерних виджета.
В моих знаниях явно есть пробел, и если кто-нибудь увидит, что это такое, я бы хотел знать!