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

Flutter:SfDataGrid选中行跳转详情页,传递Firestore文档快照问题

解决方案

要传递Firestore文档的完整字段到详情页,核心是保留原始的Firestore文档数据在数据源中,而不是只依赖表格渲染用的DataGridRow。具体步骤如下:

1. 定义包含完整字段的数据模型

先创建一个数据模型类,比如Employee,要包含Firestore文档的所有字段(包括表格未显示的内容),同时保留文档ID方便后续操作:

class Employee {
  Employee({
    required this.id,
    required this.name,
    required this.designation,
    required this.salary,
    this.email,
    this.phone,
  });

  final String id;
  final String name;
  final String designation;
  final int salary;
  final String? email;
  final String? phone;

  // 从Firestore快照转换为模型
  factory Employee.fromSnapshot(DocumentSnapshot snapshot) {
    final data = snapshot.data() as Map<String, dynamic>;
    return Employee(
      id: snapshot.id,
      name: data['name'],
      designation: data['designation'],
      salary: data['salary'],
      email: data['email'],
      phone: data['phone'],
    );
  }
}

2. 修改数据源类,存储完整模型数据

让你的EmployeeDataSource类维护一个包含完整Employee对象的列表,表格渲染只提取需要显示的列:

class EmployeeDataSource extends DataGridSource {
  EmployeeDataSource(this.employees) {
    _buildDataGridRows();
  }

  // 保存完整的Firestore文档模型列表
  final List<Employee> employees;
  List<DataGridRow> _dataGridRows = [];

  void _buildDataGridRows() {
    _dataGridRows = employees
        .map<DataGridRow>((employee) => DataGridRow(cells: [
              DataGridCell<String>(columnName: 'name', value: employee.name),
              DataGridCell<String>(columnName: 'designation', value: employee.designation),
              DataGridCell<int>(columnName: 'salary', value: employee.salary),
              // 只渲染需要显示的列,模型保留所有字段
            ]))
        .toList();
  }

  @override
  List<DataGridRow> get rows => _dataGridRows;

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      return Container(
        alignment: Alignment.center,
        padding: const EdgeInsets.all(8.0),
        child: Text(dataGridCell.value.toString()),
      );
    }).toList());
  }
}

3. 点击行时传递完整模型到详情页

在onCellTap回调中,直接从数据源的原始模型列表中获取数据,而不是从effectiveRows取DataGridRow:

onCellTap: (DataGridCellTapDetails details) {
  // 减去1是因为第一行是表头
  final int rowIndex = details.rowColumnIndex.rowIndex - 1;
  if (rowIndex >= 0 && rowIndex < employeeDataGridSource.employees.length) {
    // 获取包含所有字段的完整Employee对象
    final Employee selectedEmployee = employeeDataGridSource.employees[rowIndex];
    Navigator.of(context).push(MaterialPageRoute(
      builder: (context) => DataGridRowInfoPage(employee: selectedEmployee),
    ));
  }
},

4. 详情页接收并展示完整数据

修改详情页,接收Employee对象并展示所有字段:

class DataGridRowInfoPage extends StatelessWidget {
  final Employee employee;

  const DataGridRowInfoPage({super.key, required this.employee});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('员工详情')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('姓名: ${employee.name}'),
            Text('职位: ${employee.designation}'),
            Text('薪资: ${employee.salary}'),
            Text('邮箱: ${employee.email ?? '未填写'}'),
            Text('电话: ${employee.phone ?? '未填写'}'),
            // 可添加任意Firestore文档中的字段
          ],
        ),
      ),
    );
  }
}

关键说明

  • DataGridRow只是表格渲染的载体,仅包含你指定要显示的列数据,因此无法从中获取完整的Firestore文档信息。
  • 始终在数据源中保留原始的Firestore模型数据,这样需要时能直接获取完整信息,避免数据丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:25:16