NOTE: 相反,我最终重组了事物,消除了sibling 姐妹之间的沟通途径.
ParentWidget
|-ChildWidgetA
|-ChildWidgetB
因为我需要两个不同版本的ChildWidgetA(一个是静态的,一个带有编辑字段),并且因为我需要双向通信(sibling B向A发送命令,A将最终状态返回给B)……
一切都变得复杂起来.将"sibling " node 改为子 node ,从而使通信更容易.
教训:如果你需要sibling 姐妹之间的交流,那就努力想办法让他们成为父母/子元素.sibling 部件到sibling 部件的通信是可能的,但由于非常间接的代码流,使得代码很难跟踪.
--------- Original Post -----------个
Situation:父部件,有两个子部件.
以下是:
ParentWidget
|-ChildWidgetA
|-ChildWidgetB
ChildWidgetA包含一个数据输入表单. ChildWidgetB包含按钮(保存、取消、导出等)
ChildWidgetB中的Need操作(按钮点击)以触发ChildWidgetA中的响应(文本数据的读取和保存).
按如下方式更改父/子关系:
ParentWidget
|-ChildWidgetA
|-ChildWidgetB
...可以工作(这样子元素可以使用父母提供的回调),但在我的实际情况下是不可能的,除非没有其他可能的解决方案.
我还宁愿not将数据输入表单的知识拉到(不相关的)ParentWidget中,例如,通过为那里创建TextEditingController
个对象来帮助ControlsWidget读取文本值以进行保存.
Question:如果我更改/重新排列代码,有哪些可能性可以让它工作?(可能是流、事件侦听器、状态魔术…?)
以下是一些带注释的示例代码,演示了 struct 问题:
class ParentWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
DataEntryFormWidget(), // TextFields with values to read, save
ControlsWidgetWithSaveButton(), // Button I want to trigger the save
],
);
}
}
class DataEntryFormWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
TextFormField(), // assume I have a way to read values from these
TextFormField(),
// etc
]
);
}
void doSave() {
// read values from TextFormField()
// This is the thing I cannot do from ControlsWidgetWithSaveButton
// because that doesn't have access to TextFormField(s)...
// So can't simply move this code/function to controls widget.
//
// getDatabase.save(... the values ...)
// (all saved ok)
}
}
class ControlsWidgetWithSaveButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
ElevatedButton(
onPressed: () {
// THE PROBLEM:
// Here I want to invoke/trigger the doSave() function.
// Could do the DB write here if I had the data...
},
child: const Text('Save'),
),
// ... <assume some other buttons>
]
);
}
}