【问题标题】:How to inject data into class when Provider can't be used? - Flutter无法使用Provider时如何将数据注入类? - 颤振
【发布时间】:2021-07-03 22:37:57
【问题描述】:

我真的在为这个问题苦苦挣扎,提出正确的问题,甚至是正确的术语,所以请在这里帮助我。在我不知道的正确问题语法下,这可能是一个简单的解决方法。如果是这样,我会在知道术语后删除。

目标

我想将数据动态添加到我的 Syncfusion DataGrid。

问题

  • 我不知道如何将我的动态数据列表添加到我的 DataGridSource
  • 由于类中没有上下文,无法使用 Provider、Consumer 等
  • 在 Widget 中调用 DataGrid Consumer 中的类型时,不知道如何向类构造函数添加参数,我看不到任何可能的方式将参数传入 Consumer,因为 DataGris 源对获取的内容很挑剔
  • 创建我的数据库类的实例并将数据注入 DataGrid 源根本不起作用,数据不加载
  • 我可以看到最终这是一个状态管理问题,因此如果我在这里只学习一件事,我想学习如何将数据传递给一个独立于任何小部件的类,而无需标准的混乱 OOP 初始化
  • 注意,我确实尝试使用代理提供程序来初始化数据库数据方法 - 没有用

如果我的问题没有意义,我可以尝试扩展。但是我想做的就是使用 Consumer 动态地将数据添加到 DataGrid。

这是我使用带有硬编码数据的消费者的 Syncfusions 编码示例。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

class DataGridWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<EmployeeDataSource>(
      builder: (context, employeeDataSource, _) {
        return Scaffold(
          appBar: AppBar(
            title: Text('DataGrid Demo'),
          ),
          body: SfDataGrid(
            source: employeeDataSource,
            columnWidthMode: ColumnWidthMode.fill,
            selectionMode: SelectionMode.multiple,
            navigationMode:
                GridNavigationMode.cell, // controller: dataGridController,
            onQueryRowHeight: (details) {
              return details.rowHeight;
            },
            columns: <GridColumn>[
              GridTextColumn(
                  columnName: 'id',
                  label: Container(
                      padding: EdgeInsets.all(16.0),
                      alignment: Alignment.centerRight,
                      child: Text(
                        'ID',
                      ))),
              GridTextColumn(
                  columnName: 'name',
                  label: Container(
                      padding: EdgeInsets.all(16.0),
                      alignment: Alignment.centerLeft,
                      child: Text('Name'))),
              GridTextColumn(
                  columnName: 'designation',
                  width: 120,
                  label: Container(
                      padding: EdgeInsets.all(16.0),
                      alignment: Alignment.centerLeft,
                      child: Text('Designation'))),
              GridTextColumn(
                  columnName: 'salary',
                  label: Container(
                      padding: EdgeInsets.all(16.0),
                      alignment: Alignment.centerRight,
                      child: Text('Salary'))),
            ],
          ),
        );
      },
    );
  }
}

/// Custom business object class which contains properties to hold the detailed
/// information about the employee which will be rendered in datagrid.
class Employee {
  /// Creates the employee class with required details.
  Employee(this.id, this.name, this.designation, this.salary);

  /// Id of an employee.
  int id;

  /// Name of an employee.
  String name;

  /// Designation of an employee.
  String designation;

  /// Salary of an employee.
  int salary;
}

class EmployeeDataSource extends DataGridSource {

  EmployeeDataSource() {
    employees = getEmployeeData();
    buildDataGridRow();
  }

  void buildDataGridRow() {
    dataGridRows = employees
        .map<DataGridRow>((e) => DataGridRow(cells: [
              DataGridCell<int>(columnName: 'id', value: e.id),
              DataGridCell<String>(columnName: 'name', value: e.name),
              DataGridCell<String>(
                  columnName: 'designation', value: e.designation),
              DataGridCell<int>(columnName: 'salary', value: e.salary),
            ]))
        .toList();
  }

  List<Employee> employees = <Employee>[];

  List<DataGridRow> dataGridRows = [];

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

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((e) {
      return Container(
        alignment: (e.columnName == 'id' || e.columnName == 'salary')
            ? Alignment.centerRight
            : Alignment.centerLeft,
        padding: EdgeInsets.all(8.0),
        child: Text(e.value.toString()),
      );
    }).toList());
  }

  List<Employee> getEmployeeData() {
    return [
      Employee(10001, 'James', 'Project Lead', 20000),
      Employee(10002, 'Kathryn', 'Manager', 30000),
      Employee(10003, 'Lara', 'Developer', 15000),
      Employee(10004, 'Michael', 'Designer', 15000),
      Employee(10005, 'Martin', 'Developer', 15000),
      Employee(10006, 'Newberry', 'Developer', 15000),
      Employee(10007, 'Balnc', 'Developer', 15000),
      Employee(10008, 'Perry', 'Developer', 15000),
      Employee(10009, 'Gable', 'Developer', 15000),
      Employee(10010, 'Grimes', 'Developer', 15000),
      Employee(10010, 'Lane', 'Project Lead', 20000),
      Employee(10010, 'Doran', 'Developer', 15000),
      Employee(10010, 'Betts', 'Developer', 15000),
      Employee(10010, 'Tamer', 'Manager', 30000),
      Employee(10001, 'James', 'Project Lead', 20000),
      Employee(10002, 'Kathryn', 'Manager', 30000),
      Employee(10003, 'Lara', 'Developer', 15000),
      Employee(10004, 'Michael', 'Designer', 15000),
      Employee(10005, 'Martin', 'Developer', 15000),
      Employee(10006, 'Newberry', 'Developer', 15000),
      Employee(10007, 'Balnc', 'Developer', 15000),
      Employee(10008, 'Perry', 'Developer', 15000),
      Employee(10009, 'Gable', 'Developer', 15000),
      Employee(10010, 'Grimes', 'Developer', 15000),
      Employee(10010, 'Lane', 'Project Lead', 20000),
      Employee(10010, 'Doran', 'Developer', 15000),
      Employee(10010, 'Betts', 'Developer', 15000),
      Employee(10010, 'Tamer', 'Manager', 30000),
    ];
  }
}

【问题讨论】:

    标签: flutter datagrid syncfusion flutter-state


    【解决方案1】:

    您应该初始化数据并将数据放入 DataGrifWidgetClass 的列表中,并将列表传递给 employeeDataSource,我可以与您分享我的代码

    for(int i = 0; i <data.length; i++){
      var split = data[i]["created_at"].toString().split("T");
      cellsList.add(Cells([
        DataCell(dataCells(context,(i+1).toString(),)),
        DataCell(dataCells(context,split[0])),
        DataCell(dataCells(context,data[i]["type"])),
        DataCell(dataCells(context,data[i]["bonus_from"].toString())),
        DataCell(dataCells(context,data[i]["amount"].toString(),color: Colors.green)),
        DataCell(dataCells(context,data[i]["status"].toString())),
      ] ));
    }
    return Padding(
      padding: const EdgeInsets.symmetric( vertical: 20),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            "Bonus History",
            style: robotoStyle(
              context,
              color: Theme.of(context).primaryTextTheme.bodyText1.color,
              fontWeight: FontWeight.bold,
              fontSize: ResponsiveFlutter.of(context).fontSize(Utils.isTabletView == true?1.5:2.25),
            ),
          ),
          SizedBox(
            height: 10,
          ),
          Flexible(
            child: Card(
    
              color: Theme.of(context).primaryColor,elevation: 0,shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15),
    
                side: BorderSide(
                    color: Theme.of(context).primaryTextTheme.bodyText1.color)),
              child: CardlessHeadlessPaginatedDataTable(
                footer:provider["BonusAccounts"]["data"].length ==0?false: true,
                nextPage: provider["BonusAccounts"]["next_page_url"],
                previousPage: provider["BonusAccounts"]["prev_page_url"],
                firstPage: provider["BonusAccounts"]["first_page_url"],
                rowsPerPage:provider["BonusAccounts"]["data"].length ==0?1: provider["BonusAccounts"]["per_page"],
                columns: <DataColumn>[
                  DataColumn(label: currencyTabs(context,"Serial No.")),
                  DataColumn(label: currencyTabs(context,"Date")),
                  DataColumn(label: currencyTabs(context,"Type")),
                  DataColumn(label: currencyTabs(context,"Form")),
                  DataColumn(label: currencyTabs(context,"Amount")),
                  DataColumn(label: currencyTabs(context,"Status")),
                ],
                source:  DataSource(context,cellsList),
              ),
            ),
          ),
        ],
      ),
    );
    
    
    
    
    
    
    
    
        class DataSource extends DataTableSource {
          final cellsList;
          DataSource(this.context,this.cellsList) {
        
            // _rows = list;
          }
        
          final BuildContext context;
          List<DataTableRows> _rows;
        
        
          int _selectedCount = 0;
        
          @override
          DataRow getRow(int index) {
            assert(index >= 0);
        
        
                if(cellsList.length != index)
                  {
                    if(index%2 ==0) {
                      return DataRow(
        
                        color: MaterialStateProperty.all(Theme
                            .of(context)
                            .primaryColor),
                        cells: [
                          for(int j = 0; j < cellsList[index].cells.length; j++)
                            cellsList[index].cells[j],
        
                        ],
                      );
                    }else{
                      return DataRow(
                        color: MaterialStateProperty.all(Theme
                            .of(context)
                            .bottomAppBarColor),
                        cells: [
                          for(int j = 0; j < cellsList[index].cells.length; j++)
                            cellsList[index].cells[j],
        
                        ],
                      );
                    }
                  }
          }
        
          @override
          int get rowCount => cellsList.length;
        
          @override
          bool get isRowCountApproximate => false;
        
          @override
          int get selectedRowCount => _selectedCount;
        }
    

    【讨论】:

    • 这可以运行,但是它会不断运行,消耗大量资源甚至为模拟器加热 CPU。例如,我将 print 语句放入构造函数中,它每秒打印几次并且非常快速地爬升:如果我这样做:DataSource(this.context,this.cellsList) { print('loaded'); // _rows = list; } 我得到这个打印输出 // 560+ 颤振:加载
    • 抱歉,我刚刚意识到我需要在提供程序中设置listen: false。这工作谢谢你
    猜你喜欢
    • 2017-10-23
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2020-08-13
    • 1970-01-01
    • 2021-04-29
    相关资源
    最近更新 更多