簡體   English   中英

Flutter 分頁數據表未來因鏈接請求而失敗

[英]Flutter PaginatedDataTable Future failed with chained request

我在 Flutter Web (1.20.0-8.0.pre2) 中的 PaginatedDataTable 有問題:我必須鏈接兩個未來的請求,一個取決於第一個。 例如:第一個請求返回一個 json 任務數組:

[ ["field1", "field2", 154631565, "field4"],["field5", "field6", 7862626, "field8"] ]"

3d position 中的數字是用戶的 id。 使用此獲取用戶的第二個請求是:

[ 154631565, "John", "Doe"]

我的代碼基於此: https://github.com/AseemWangoo/experiments_with_web/tree/master/lib/data_tablehttps://flatteredwithflutter.com/using-paginateddatatable-in-flutter-web/

如果我只請求第一個端點,一切正常,但我在表中有 Id,而不是 Name 和 First Name。

任務數據表API:

class TaskDataTableApi {
  TaskDataTableApi._();

  static Future<List<TaskModel>> fetchData() async {
    final _completer = Completer<List<TaskModel>>();

    try {
      final response = await http.get(_query);

      if (response.statusCode == 200) {
        // print(response.body);
        final _data = taskModelFromJson(response.body.replaceAll(r'\t', ' '));
        _completer.complete(_data);
      } else {
        print('Error, Could not load Data');
        throw Exception('Failed to load Data');
      }
    } catch (exc) {
      _completer.completeError(<TaskModel>[]);
    }

    return _completer.future;
  }
}

用戶數據表接口:

class UserDataTableApi {
  UserDataTableApi._();

  static Future<List<UserModel>> fetchData(maxRows) async {
    final _completer = Completer<List<UserModel>>();
    String _query = url;
    _query += 'selectQuery?loginName=' + loginName;
    _query += '&password=' + password;
    _query += '&custId=' + custId;
    _query += '&maxRows= ' + maxRows;
    _query += '&output=json&';
    _query += 'query=SELECT id, firstName,lastName, photo FROM USER';

    try {
      final response = await http.get(_query);

      if (response.statusCode == 200) {
        print(response.body);
        final _data = userModelFromJson(response.body.replaceAll(r'\t', ' '));
        _completer.complete(_data);
      } else {
        print('Error, Could not load Data');
        throw Exception('Failed to load Data');
      }
    } catch (exc) {
      _completer.completeError(<UserModel>[]);
    }

    return _completer.future;
  }

  static Future<List<UserModel>> getOneById(int id) async {
    final _completer = Completer<List<UserModel>>();
    try {
      final response = await http.get(_query);

      if (response.statusCode == 200) {
        //print(response.body);
        final _data = userModelFromJson(response.body.replaceAll(r'\t', ' '));
        _completer.complete(_data);
      } else {
        print('Error, Could not load Data');
        throw Exception('Failed to load Data');
      }
    } catch (exc) {
      _completer.completeError(<UserModel>[]);
    }

    return _completer.future;
  }
}

任務數據表通知程序

class TaskDataNotifier with ChangeNotifier {
  TaskDataNotifier() {
    fetchData();
  }

  List<TaskModel> get taskModel => _taskModel;

  int get sortColumnIndex => _sortColumnIndex;

  set sortColumnIndex(int sortColumnIndex) {
    _sortColumnIndex = sortColumnIndex;
    notifyListeners();
  }

  bool get sortAscending => _sortAscending;

  set sortAscending(bool sortAscendindg) {
    _sortAscending = sortAscending;
    notifyListeners();
  }

  int get rowsPerPage => _rowsPerPage;

  set rowsPerPage(int rowsPerPage) {
    _rowsPerPage = rowsPerPage;
    notifyListeners();
  }

  var _taskModel = <TaskModel>[];

  int _sortColumnIndex;
  bool _sortAscending = true;
  int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;

  Future<void> fetchData() async {
    _taskModel = await TaskDataTableApi.fetchData();
    for (TaskModel _row in _taskModel) {
      if (_row.dev != null) {
        print(_row.dev);
        // List<UserModel> _user = await UserDataTableApi.getOneById(_row.dev);
        // print(_user[0].firstName);
      }
    }

    notifyListeners();
  }
}

和帶有數據表的頁面:

class MyTasksList extends StatelessWidget {
  const MyTasksList({Key key}) : super(key: key);

  static const String routeName = '/tasks';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MyAppBar(),
      drawer: MyDrawer(),
      body: ChangeNotifierProvider<TaskDataNotifier>(
        create: (_) => TaskDataNotifier(),
        child: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Center(
            child: Container(
              width: 1500.0,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Padding(
                    padding: EdgeInsets.only(
                      top: 10.0,
                    ),
                    child: _MyTasksList(),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class _MyTasksList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _provider = context.watch<TaskDataNotifier>();
    final _model = _provider.taskModel;

    if (_model.isEmpty) {
      return const SizedBox.shrink();
    }

    final _dtSource = TaskDataTableSource(
      //onRowSelect: (index) => _showDetails(context, _model[index]),
      onRowSelect: (index) => print("Pressed"),
      taskData: _model,
    );

    return PaginatedDataTable(
      actions: <IconButton>[
        IconButton(
          splashColor: Colors.transparent,
          icon: const Icon(Icons.refresh),
          onPressed: () {
            _provider.fetchData();
            _showSBar(context, "Refresh successful");
          },
        ),
      ],
      header: Text('Task List'),
      columns: myColumns(_dtSource, _provider),
      source: _dtSource,
      onRowsPerPageChanged: (rowsPerPage) {
        _provider.rowsPerPage = rowsPerPage;
      },
      sortAscending: _provider.sortAscending,
      sortColumnIndex: _provider.sortColumnIndex,
      rowsPerPage: _provider.rowsPerPage,
    );
  }

  List<DataColumn> myColumns(
    TaskDataTableSource _src,
    TaskDataNotifier _provider,
  ) =>
      <DataColumn>[
        DataColumn(
          label: Text('Type'),
          onSort: (colIndex, asc) {
            _sort<num>((task) => task.taskType, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Name'),
          onSort: (colIndex, asc) {
            _sort<String>((task) => task.name, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('?'),
        ),
        DataColumn(
          label: Text('Origin'),
          onSort: (colIndex, asc) {
            _sort<num>(
                (task) => task.customerId, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Customer'),
          onSort: (colIndex, asc) {
            _sort<num>(
                (task) => task.customerId, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Complexity'),
          onSort: (colIndex, asc) {
            _sort<num>(
                (task) => task.complexity, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Value'),
          onSort: (colIndex, asc) {
            _sort<num>((task) => task.value, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Dev'),
          onSort: (colIndex, asc) {
            _sort<num>((task) => task.dev, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Corr'),
          // onSort: (colIndex, asc) {
          //   _sort<num>((task) => task.cor, colIndex, asc, _src, _provider);
          // },
        ),
        DataColumn(
          label: Text('Status'),
        ),
        DataColumn(
          label: Text('Created on'),
          onSort: (colIndex, asc) {
            _sort<DateTime>(
                (task) => task.createdOn, colIndex, asc, _src, _provider);
          },
        ),
        DataColumn(
          label: Text('Canceled on'),
        ),
        DataColumn(
          label: Text('Super Score'),
        ),
      ];

  void _sort<T>(
    Comparable<T> Function(TaskModel task) getField,
    int colIndex,
    bool asc,
    TaskDataTableSource _src,
    TaskDataNotifier _provider,
  ) {
    _src.sort<T>(getField, asc);
    _provider.sortAscending = asc;
    _provider.sortColumnIndex = colIndex;
  }

  void _showSBar(BuildContext c, String textToShow) {
    Scaffold.of(c).showSnackBar(
      SnackBar(
        content: Text(textToShow),
        duration: const Duration(milliseconds: 2000),
      ),
    );
  }
}

我試圖在通知程序中調用 await then(),我看到第二個請求被觸發,但隨后應用程序失敗。

感謝幫助。

我終於找到了一種方法來做到這一點。 我在一個有狀態的小部件中更改了主小部件,並添加了一個 FutureBuilder。 我刪除了 Provider class 並使用 setState() 對 DataTable 執行操作。 有了它,我可以做多次等待,我的完整數據也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM