Flutter - 如何在 parent 事件或操作上访问 child 数据

Flutter - How to access child data on parent event or action

我有一个更长的输入表单,用户可以在其中添加许多相同的子表单。

例如考虑一个表单,其中 parents 可以输入他们的数据(父表单),然后添加他们的 child。由于我不知道用户有多少 child,他们可以使用按钮动态添加更多 child 表单。

对于每个 child 请求的数据都是相同的,例如姓名、生日、性别,实际上大约有 10 个字段。所以我创建了一个单独的小部件 (childform)。

如果用户现在保存外部表单,我需要从 child 表单中收集所有信息。我现在可以通过在父表单中创建所有 TextController 来做到这一点,将它们保存在列表中并在创建 child 表单时插入它们,如下所示:

void addTextField() {
  int index = _childNameControllers.length;
  _childNameControllers.add( TextEditingController());

  _childforms.add(
    RemovableEntityField(
      nameController: _childNameControllers[index]
    )
  );
}

然后保存类似

void onSave() {
  List<Childs> _childs = [];
  _childNameControllers.forEach((controller) {
    if (controller.text.trim().isNotEmpty) {
      _childs.add(Child(name: name));
    }
  });
  // do something with the data
}

但正如我所说,每个 child 表单大约有 10 个字段,我必须为每个表单创建 10 个控制器,并且 child 表单中需要 10 个参数才能读取此信息.
有更简单的方法吗?

PS:我知道我可以达到 child 状态 public 但我也不想这样做

我相信你应该在 child 中添加变量更新程序并将值推到 parent。

https://github.com/flutter/flutter/tree/4b4cff94bf6631bf6326c9239c10b286b4fdb08c/dev/benchmarks/test_apps/stocks

flutter stock 应用有一个例子。

在 child 你需要这个。

class StockSettings extends StatefulWidget {
  const StockSettings(this.configuration, this.updater);

  final StockConfiguration configuration;
  final ValueChanged<StockConfiguration> updater;

  @override
  StockSettingsState createState() => StockSettingsState();
}

class StockSettingsState extends State<StockSettings> {
void _handleBackupChanged(bool value) {
    sendUpdates(widget.configuration.copyWith(backupMode: value ? BackupMode.enabled : BackupMode.disabled));
}

void sendUpdates(StockConfiguration value) {
    if (widget.updater != null)
      widget.updater(value);
}

在 parent 中,您传递配置更新器,它只是设置状态的包装器

class StocksAppState extends State<StocksApp> {
  StockData stocks;

  StockConfiguration _configuration = StockConfiguration(
    stockMode: StockMode.optimistic,
    backupMode: BackupMode.enabled,
    debugShowGrid: false,
    debugShowSizes: false,
    debugShowBaselines: false,
    debugShowLayers: false,
    debugShowPointers: false,
    debugShowRainbow: false,
    showPerformanceOverlay: false,
    showSemanticsDebugger: false
  );

  @override
  void initState() {
    super.initState();
    stocks = StockData();
  }

  void configurationUpdater(StockConfiguration value) {
    setState(() {
      _configuration = value;
    });
}

routes: <String, WidgetBuilder>{
         '/':         (BuildContext context) => StockHome(stocks, _configuration, configurationUpdater),
         '/settings': (BuildContext context) => StockSettings(_configuration, configurationUpdater)
},