You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何将类内变量传入Future函数更新Firestore数据?

解决方法

核心思路是让updateData函数接收文档引用作为参数,点击保存按钮时直接把当前条目的Firestore文档引用传递进去即可,具体实现如下:

步骤1:修改updateData函数,添加文档引用参数

把原本无参的updateData改成带DocumentReference参数的函数,直接用传入的引用执行更新操作:

Future updateData(DocumentReference docRef) async {
  await docRef.update({
    'name': controllerName.text,
  }).then((value) => print('updated.'));
}

步骤2:在条目构建方法中传递文档引用

在_buildListItem里给文档引用定义一个明确的变量(比如docRef),然后在调用updateData时把这个变量传进去:

DataRow _buildListItem(BuildContext context, DocumentSnapshot data) {
  // 定义当前条目的Firestore文档引用
  final docRef = FirebaseFirestore.instance
      .collection('testinfo')
      .doc(data.id);

  return DataRow(cells: [
    DataCell(Text(data['name']!)),
    DataCell(Row(children: [
      PopupMenuButton<Menu>(
        padding: const EdgeInsets.only(right: 2, left: 1, top: 2),
        onSelected: (value) async {
          if (value == Menu.itemOne) {
            controllerName.text = data.get('name');
            showDialog(
              context: context,
              builder: (context) => Dialog(
                child: Container(
                  color: primaryColor,
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ListView(
                      shrinkWrap: true,
                      children: <Widget>[
                        TextField(
                          onChanged: (value) {
                            candidateName = value;
                          },
                          controller: controllerName,
                          decoration: const InputDecoration(
                            hintText: 'name',
                          ),
                        ),
                        const SizedBox(height: 16),
                        ElevatedButton(
                          // 传入当前条目的文档引用
                          onPressed: () => updateData(docRef),
                          child: const Text('Save'),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            );
          }
        },
        itemBuilder: (BuildContext context) => const <PopupMenuEntry<Menu>>[
          PopupMenuItem<Menu>(
            value: Menu.itemTwo,
            child: Text('edit'),
          ),
        ],
      ),
    ])),
  ]);
}

完整修正后的代码

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

// 补充代码中用到的Menu枚举
enum Menu { itemOne, itemTwo }

class Test extends StatefulWidget {
  const Test({Key? key}) : super(key: key);

  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  final Stream<QuerySnapshot> _usersStream =
      FirebaseFirestore.instance.collection('testinfo').snapshots();
  // 补充代码中用到的控制器和变量
  final TextEditingController controllerName = TextEditingController();
  String candidateName = '';
  // 补充代码中用到的常量定义
  final double defaultPadding = 16.0;
  final Color primaryColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(defaultPadding),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          StreamBuilder<QuerySnapshot>(
            stream: _usersStream,
            builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
              if (snapshot.hasError) {
                return const Center(child: CircularProgressIndicator());
              }

              if (snapshot.connectionState == ConnectionState.waiting) {
                return const Center(child: Text("Loading"));
              }

              return SizedBox(
                width: double.infinity,
                child: DataTable(
                  columnSpacing: defaultPadding,
                  columns: const [
                    DataColumn(
                      label: Text('Text'),
                    ),
                  ],
                  rows: _buildList(context, snapshot.data!.docs),
                ),
              );
            },
          ),
        ],
      ),
    );
  }

  List<DataRow> _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
    return snapshot.map((data) => _buildListItem(context, data)).toList();
  }

  DataRow _buildListItem(BuildContext context, DocumentSnapshot data) {
    final docRef = FirebaseFirestore.instance
        .collection('testinfo')
        .doc(data.id);

    return DataRow(cells: [
      DataCell(Text(data['name']!)),
      DataCell(Row(children: [
        PopupMenuButton<Menu>(
          padding: const EdgeInsets.only(right: 2, left: 1, top: 2),
          onSelected: (value) async {
            if (value == Menu.itemOne) {
              controllerName.text = data.get('name');
              showDialog(
                context: context,
                builder: (context) => Dialog(
                  child: Container(
                    color: primaryColor,
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: ListView(
                        shrinkWrap: true,
                        children: <Widget>[
                          TextField(
                            onChanged: (value) {
                              candidateName = value;
                            },
                            controller: controllerName,
                            decoration: const InputDecoration(
                              hintText: 'name',
                            ),
                          ),
                          const SizedBox(height: 16),
                          ElevatedButton(
                            onPressed: () => updateData(docRef),
                            child: const Text('Save'),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              );
            }
          },
          itemBuilder: (BuildContext context) => const <PopupMenuEntry<Menu>>[
            PopupMenuItem<Menu>(
              value: Menu.itemTwo,
              child: Text('edit'),
            ),
          ],
        ),
      ])),
    ]);
  }

  Future updateData(DocumentReference docRef) async {
    await docRef.update({
      'name': controllerName.text,
    }).then((value) => print('updated.'));
  }
}

内容的提问来源于stack exchange,提问作者matto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:35:22