我正在编写具有基本CRUD功能的Flutter应用程序。 我有用于显示项目列表,项目明细视图和编辑项目表单的屏幕。
当我从列表视图中点击项目的详细信息屏幕时,在最初创建项目后(使用单独的表单)数据可以正确呈现。
当我点击编辑表单时,从该详细信息屏幕中,该项目的数据将通过并预先填充在表单中。
当我对该项目的数据进行更改并保存更改时,我将返回到详细信息视图,但是该视图中的任何细节都没有更改。
但是,当我再上一层树时,列表视图中的项目已更新。
我在这里想念什么?如果具有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
被表单调用,它们都应该重新渲染。
当前,只有顶层列表视图显示更新后的数据,状态并没有通过两个子窗口小部件。
我的知识上显然有差距,如果有人可以看到它,我很想知道!