Flutter PaginatedDataTable 服务器端具有异步功能的分页错误

问题描述 投票:0回答:1

我的项目中有这个“屏幕”:

import 'dart:convert';
import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:medlabo_desktop/models/search_result.dart';
import 'package:medlabo_desktop/models/test/test.dart';
import 'package:medlabo_desktop/models/test/test_request.dart';
import 'package:medlabo_desktop/models/test_parametar/test_parametar.dart';
import 'package:medlabo_desktop/models/test_parametar/test_parametar_request.dart';
import 'package:medlabo_desktop/providers/test_parametri_provider.dart';
import 'package:medlabo_desktop/providers/testovi_and_test_parametri_provider.dart';
import 'package:medlabo_desktop/providers/testovi_provider.dart';
import 'package:medlabo_desktop/utils/constants/design.dart';
import 'package:medlabo_desktop/utils/constants/nums.dart';
import 'package:medlabo_desktop/utils/general/dialog_utils.dart';
import 'package:medlabo_desktop/utils/general/toast_utils.dart';
import 'package:medlabo_desktop/utils/general/util.dart';
import 'package:provider/provider.dart';

class TestoviDataTableSource extends DataTableSource {
  final TestoviProvider _provider;
  final BuildContext context;
  List<Test> _data = [];
  int _totalDataCount = 0;

  TestoviDataTableSource(this._provider, this.context);

  Future fetchData(int page) async {
    var filter = {'Page': page - 1, 'PageSize': 2};
    var result = await _provider.get(filter: filter);
    _data = result.result;
    _totalDataCount = result.count;
    notifyListeners();
  }

//zašto neće da vrati index na 0 kad se prebaci strana?
  @override
  DataRow getRow(int index) {
    if (index >= _data.length) {
      return DataRow(
          cells: List.generate(
              6, (index) => DataCell(CircularProgressIndicator())));
    }
    final test = _data[index];
    return DataRow(cells: [
      DataCell(
        Container(
          width: 100.0,
          child: GestureDetector(
            onTap: () {
              (test.naziv?.length ?? 0) > 12
                  ? showDialog(
                      context: context,
                      builder: (context) {
                        return AlertDialog(
                          content: Text(test.naziv ?? 'Nema naziv'),
                        );
                      },
                    )
                  : null;
            },
            child: Text(
              test.naziv ?? 'Nema naziv',
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ),
      ),
      DataCell(
        Container(
          width: 150.0,
          child: GestureDetector(
            onTap: () {
              (test.opis?.length ?? 0) > 20
                  ? showDialog(
                      context: context,
                      builder: (context) {
                        return AlertDialog(
                          content: Text(test.opis ?? 'Nema opis'),
                        );
                      },
                    )
                  : null;
            },
            child: Text(
              test.opis ?? 'Nema opis',
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ),
      ),
      DataCell(Text(
        formatNumberToPrice(test.cijena),
        overflow: TextOverflow.fade,
      )),
      DataCell(
        Container(
          width: 150.0,
          child: GestureDetector(
            onTap: () {
              (test.napomenaZaPripremu?.length ?? 0) > 20
                  ? showDialog(
                      context: context,
                      builder: (context) {
                        return AlertDialog(
                          content:
                              Text(test.napomenaZaPripremu ?? 'Nema napomenu'),
                        );
                      },
                    )
                  : null;
            },
            child: Text(
              test.napomenaZaPripremu ?? 'Nema napomenu',
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ),
      ),
      DataCell(Text(
        test.dtKreiranja == null
            ? 'Nepoznat'
            : formatDateTime(test.dtKreiranja!) ?? 'Nepoznat',
        overflow: TextOverflow.fade,
      )),
      DataCell(
        //_buildOptionsForTest(context, test),
        Text('opcije'),
      ),
    ]);
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => _totalDataCount;

  @override
  int get selectedRowCount => 0;
}

class TestoviScreen extends StatefulWidget {
  const TestoviScreen({super.key});

  @override
  State<TestoviScreen> createState() => _TestoviScreenState();
}

class _TestoviScreenState extends State<TestoviScreen> {
  late TestoviProvider _testoviProvider;
  late TestParametriProvider _testParametriProvider;
  late TestoviAndTestParametriProvider _testoviAndTestParametriProvider;
  SearchResult<Test>? testovi;
  TextEditingController _testSearchController = new TextEditingController();
  final _formKey = GlobalKey<FormBuilderState>();
  late TestoviDataTableSource _dataSource;

  @override
  void initState() {
    super.initState();
    _testoviProvider = context.read<TestoviProvider>();
    _dataSource = TestoviDataTableSource(_testoviProvider, context);
    _dataSource.fetchData(1);
    initForm();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _testParametriProvider = context.read<TestParametriProvider>();
    _testoviAndTestParametriProvider =
        context.read<TestoviAndTestParametriProvider>();
  }

  bool _isDataLoaded = false;

  Future initForm() async {
    var data = await _testoviProvider.get();
    if (mounted) {
      setState(() {
        testovi = data;
        _isDataLoaded = true;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(10.0),
      child: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(6),
          boxShadow: [
            BoxShadow(
              color: Colors.grey.withOpacity(0.5),
              spreadRadius: 1,
              blurRadius: 7,
              offset: const Offset(0, 3),
            ),
          ],
        ),
        child: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.fromLTRB(15, 10, 15, 0),
                child: _buildTestoviHeader(),
              ),
              Padding(
                padding: const EdgeInsets.all(10),
                child: _buildTestoviDataTable(context),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Row _buildTestoviDataTable(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.max,
      children: [
        Expanded(
          child: _isDataLoaded == true
              ? PaginatedDataTable(
                  rowsPerPage: 2,
                  onPageChanged: (int page) async {
                    await _dataSource.fetchData(page);
                  },
                  columns: const [
                    DataColumn(
                        label: Tooltip(
                      message: 'Ime testa',
                      child: Text(
                        'Naziv',
                        overflow: TextOverflow.ellipsis,
                      ),
                    )),
                    DataColumn(
                        label: Tooltip(
                      message: 'Kratak opis testa',
                      child: Text(
                        'Opis',
                        overflow: TextOverflow.ellipsis,
                      ),
                    )),
                    DataColumn(
                        label: Tooltip(
                      message: 'Cijena jednog testa',
                      child: Text(
                        'Cijena',
                        overflow: TextOverflow.ellipsis,
                      ),
                    )),
                    DataColumn(
                        label: Tooltip(
                      message:
                          'Upute koje se trebaju slijediti prije dolaska na test',
                      child: Text(
                        'Napomena za pripremu',
                        overflow: TextOverflow.ellipsis,
                      ),
                    )),
                    DataColumn(
                        label: Tooltip(
                      message: 'Datum kada je kreiran test',
                      child: Text(
                        'Datum kreiranja',
                        overflow: TextOverflow.ellipsis,
                      ),
                    )),
                    DataColumn(label: Text('Opcije')),
                  ],
                  source: _dataSource,
                )
              : const FittedBox(
                  fit: BoxFit.scaleDown,
                  child: SizedBox(
                      width: 50,
                      height: 50,
                      child: CircularProgressIndicator()),
                ),
        ),
      ],
    );
  }//and another code

现在,正如大家所看到的,我正在尝试使用 PagulatedDataTable 进行服务器端分页,因为我的后端具有分页逻辑,因此通过 get 请求,我可以获取特定页面的记录和所有记录的计数。当我打开屏幕时,我得到PaginatedDataTable,并且我得到第一页就好了,但是当我更改到第二页时,我没有得到错误,但其列具有无限加载的循环加载器的行,然后当我返回第一页时,我得到错误:“在 882 毫秒内重新加载了 1225 个库中的 3 个(编译:385 毫秒,重新加载:203 毫秒,重新汇编:198 毫秒)。 [错误:flutter/runtime/dart_vm_initializer.cc(41)] 未处理的异常:异常:获取请求失败 #0 BaseProvider.get(包:medlabo_desktop/providers/base_provider.dart:49:5) #1 TestoviDataTableSource.fetchData(包:medlabo_desktop/screens/administrator/testovi_screen.dart:34:18) #2 _TestoviScreenState._buildTestoviDataTable。 (包:medlabo_desktop/screens/administrator/testovi_screen.dart:239:21) “。我在调试时看到的奇怪行为是,当我切换到第二页时,它会进入方法 fetchData 并进入

var result = await _provider.get(filter: filter);
行,之后它不会继续在该函数中执行操作,而是转到 getRow 函数重写立即,该函数中的内容执行。为什么会发生这种情况?

我尝试了一切:'(

flutter dart pagination frontend desktop-application
1个回答
0
投票

PaginatedDataTable 不支持异步获取数据,请检查:https://github.com/flutter/flutter/issues/87348

您可以尝试使用此插件:https://pub.dev/packages/data_table_2

还有讨论中提到的其他插件:https://pub.dev/packages/advanced_datatable

无论如何,我也必须处理这个问题,最终我使用了常规的 DataTable 并自己进行了分页。

© www.soinside.com 2019 - 2024. All rights reserved.