我想要创建一个面板,在其中我可以看到存储在我的防火墙中的所有用户数据。对于这个任务,我决定使用responsive_table:^0.2.0+2代码。(https://pub.dev/packages/responsive_table)这是一个具有硬编码数据的表。
为了进行更好的概述,我决定在页面布局文件和方法/变量文件中划分代码。
DataPage是我的概览页面,其中我有页面布局,而TestTable是方法和变量的页面。在使用防火墙将数据连接到表之前,我尝试使用实际工作的硬编码数据。但是,在实现了与我的防火墙的连接之后,我得到了错误(当我运行代码时):
Error: RangeError (end): Invalid value: Not in inclusive range 0..2: 10
at Object.throw_ [as throw] (http://localhost:51303/dart_sdk.js:5646:11)
at RangeError.checkValidRange (http://localhost:51303/dart_sdk.js:136032:21)
at [dartx.getRange] (http://localhost:51303/dart_sdk.js:18141:25)
at test_table.TestTable.init.mockPullData (http://localhost:51303/packages/bestfitnesstrackereu/pages/user_administration/test_table.dart.lib.js:227:63)
at mockPullData.next (<anonymous>)
at http://localhost:51303/dart_sdk.js:43211:33
at _RootZone.runUnary (http://localhost:51303/dart_sdk.js:42983:58)
at _FutureListener.thenAwait.handleValue (http://localhost:51303/dart_sdk.js:37734:29)
at handleValueCallback (http://localhost:51303/dart_sdk.js:38329:49)
at _Future._propagateToListeners (http://localhost:51303/dart_sdk.js:38367:17)
at [_completeWithValue] (http://localhost:51303/dart_sdk.js:38196:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:51303/dart_sdk.js:38232:35)
at Object._microtaskLoop (http://localhost:51303/dart_sdk.js:43360:13)
at _startMicrotaskLoop (http://localhost:51303/dart_sdk.js:43366:13)
at http://localhost:51303/dart_sdk.js:38600:9
此外,我还得到一个永久加载符号(标题下方的蓝色栏):
我找不到原因,为什么我会犯这个错误。我希望你能帮助我。
编辑:
我刚发现,这页还能用。当我单击“每页行”并选择任意数字(10、20、50、100)时,页面将刷新并显示我的防火墙中的用户。这只是一个初始化问题。
现在我只需要找出问题所在并解决它。
编辑2:
我将initializeData()方法更改为:
usersTableSource = sourceFiltered.getRange(0, currentPerPage).toList();
至:
usersTableSource = sourceFiltered.getRange(0, _users.length).toList();
现在初始化不需要最小数量的currentPerPage作为内容。
问题求解
DataPage.dart代码:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:responsive_table/responsive_table.dart';
import 'package:bestfitnesstrackereu/pages/user_administration/test_table.dart';
class DataPage extends StatefulWidget {
DataPage({Key key}) : super(key: key);
@override
_DataPageState createState() => _DataPageState();
}
class _DataPageState extends State<DataPage> {
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
final TestTable testTable = Provider.of<TestTable>(context);
return Scaffold(
appBar: AppBar(
title: Text("RESPONSIVE DATA TABLE"),
),
drawer: Drawer(
child: ListView(
children: [
ListTile(
leading: Icon(Icons.home),
title: Text("home"),
onTap: () {},
),
ListTile(
leading: Icon(Icons.storage),
title: Text("data"),
onTap: () {},
)
],
),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(0),
constraints: BoxConstraints(
maxHeight: 700,
),
child: Card(
elevation: 1,
shadowColor: Colors.black,
clipBehavior: Clip.none,
child: ResponsiveDatatable(
title: TextButton.icon(
onPressed: () => {},
icon: Icon(Icons.add),
label: Text("new item"),
),
reponseScreenSizes: [ScreenSize.xs],
actions: [
if (testTable.isSearch)
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: 'Enter search term based on ' +
testTable.searchKey
.replaceAll(new RegExp('[\\W_]+'), ' ')
.toUpperCase(),
prefixIcon: IconButton(
icon: Icon(Icons.cancel),
onPressed: () {
setState(() {
testTable.isSearch = false;
});
testTable.initializeData();
}),
suffixIcon: IconButton(
icon: Icon(Icons.search), onPressed: () {})),
onSubmitted: (value) {
testTable.filterData(value);
},
)),
if (!testTable.isSearch)
IconButton(
icon: Icon(Icons.search),
onPressed: () {
setState(() {
testTable.isSearch = true;
});
})
],
headers: testTable.headers,
source: testTable.usersTableSource,
selecteds: testTable.selecteds,
showSelect: testTable.showSelect,
autoHeight: false,
dropContainer: (data) {
if (int.tryParse(data['id'].toString()).isEven) {
return Text("is Even");
}
return _DropDownContainer(data: data);
},
onChangedRow: (value, header) {
/// print(value);
/// print(header);
},
onSubmittedRow: (value, header) {
/// print(value);
/// print(header);
},
onTabRow: (data) {
print(data);
},
onSort: testTable.onSort,
expanded: testTable.expanded,
sortAscending: testTable.sortAscending,
sortColumn: testTable.sortColumn,
isLoading: testTable.isLoading,
onSelect: testTable.onSelected,
onSelectAll: testTable.onSelectAll,
footers: [
Container(
padding: EdgeInsets.symmetric(horizontal: 15),
child: Text("Rows per page:"),
),
if (testTable.perPages.isNotEmpty)
Container(
padding: EdgeInsets.symmetric(horizontal: 15),
child: DropdownButton<int>(
value: testTable.currentPerPage,
items: testTable.perPages
.map((e) => DropdownMenuItem<int>(
child: Text("$e"),
value: e,
))
.toList(),
onChanged: testTable.onChanged,
isExpanded: false,
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 15),
child:
Text("$testTable.currentPage - $testTable.currentPerPage of $testTable.total"),
),
IconButton(
icon: Icon(
Icons.arrow_back_ios,
size: 16,
),
onPressed: testTable.previous,
padding: EdgeInsets.symmetric(horizontal: 15),
),
IconButton(
icon: Icon(Icons.arrow_forward_ios, size: 16),
onPressed: testTable.next,
padding: EdgeInsets.symmetric(horizontal: 15),
)
],
),
),
),
])),
floatingActionButton: FloatingActionButton(
onPressed: testTable.initializeData,
child: Icon(Icons.refresh_sharp),
),
);
}
}
class _DropDownContainer extends StatelessWidget {
final Map<String, dynamic> data;
const _DropDownContainer({Key key, @required this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
List<Widget> _children = data.entries.map<Widget>((entry) {
Widget w = Row(
children: [
Text(entry.key.toString()),
Spacer(),
Text(entry.value.toString()),
],
);
return w;
}).toList();
return Container(
/// height: 100,
child: Column(
/// children: [
/// Expanded(
/// child: Container(
/// color: Colors.red,
/// height: 50,
/// )),
/// ],
children: _children,
),
);
}
}
TestTable.dart代码:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:responsive_table/responsive_table.dart';
import '../../datamodels/user_model.dart';
import '../../services/user_services.dart';
class TestTable with ChangeNotifier {
List<int> perPages = [10, 20, 50, 100];
int total = 100;
int currentPerPage = 10;
List<bool> expanded;
String searchKey = "id";
int currentPage = 1;
bool isSearch = false;
List<Map<String, dynamic>> sourceOriginal = [];
List<Map<String, dynamic>> sourceFiltered = [];
List<Map<String, dynamic>> usersTableSource = [];
List<Map<String, dynamic>> selecteds = [];
// ignore: unused_field
String selectableKey = "id";
String sortColumn;
bool sortAscending = true;
bool isLoading = true;
bool showSelect = true;
var random = new Random();
List<DatatableHeader> headers = [
DatatableHeader(
text: "UID",
value: "uid",
show: true,
sortable: true,
textAlign: TextAlign.left),
DatatableHeader(
text: "Benutzername",
value: "username",
show: true,
sortable: true,
textAlign: TextAlign.left),
DatatableHeader(
text: "E-Mail",
value: "email",
show: true,
sortable: true,
textAlign: TextAlign.left),
DatatableHeader(
text: "Vorname",
value: "first name",
show: true,
sortable: true,
textAlign: TextAlign.left),
DatatableHeader(
text: "Nachname",
value: "last name",
show: true,
sortable: true,
textAlign: TextAlign.left),
DatatableHeader(
text: "Geburtsdatum",
value: "birthday",
show: true,
sortable: true,
textAlign: TextAlign.left),
DatatableHeader(
text: "Geschlecht",
value: "gender",
show: true,
sortable: true,
textAlign: TextAlign.left),
];
UserServices _userServices = UserServices();
List<UserModel> _users = <UserModel>[];
List<UserModel> get users => _users;
Future _loadFromFirebase() async {
_users = await _userServices.getAllUsers();
}
List<Map<String, dynamic>> _getUsersData() {
List<Map<String, dynamic>> temps = [];
var i = _users.length;
print(i);
// ignore: unused_local_variable
for (UserModel userData in _users) {
temps.add({
"uid": userData.uid,
"username": userData.username ,
"email": userData.email ,
"first name": userData.firstName ,
"last name": userData.lastName ,
"birthday": userData.birthday ,
"gender": userData.gender ,
});
i++;
}
return temps;
}
initializeData() async {
mockPullData();
}
mockPullData() async {
expanded = List.generate(currentPerPage, (index) => false);
isLoading = true;
notifyListeners();
await _loadFromFirebase();
sourceOriginal.clear();
sourceOriginal.addAll(_getUsersData());
sourceFiltered = sourceOriginal;
total = sourceFiltered.length;
usersTableSource = sourceFiltered.getRange(0, currentPerPage).toList();
isLoading = false;
notifyListeners();
}
resetData({start: 0}) async {
isLoading = true;
notifyListeners();
var _expandedLen =
total - start < currentPerPage ? total - start : currentPerPage;
expanded = List.generate(_expandedLen as int, (index) => false);
usersTableSource.clear();
usersTableSource = sourceFiltered.getRange(start, start + _expandedLen).toList();
isLoading = false;
notifyListeners();
//hier future weggemacht
}
filterData(value) {
isLoading = true;
notifyListeners();
try {
if (value == "" || value == null) {
sourceFiltered = sourceOriginal;
} else {
sourceFiltered = sourceOriginal
.where((data) => data[searchKey]
.toString()
.toLowerCase()
.contains(value.toString().toLowerCase()))
.toList();
}
total = sourceFiltered.length;
var _rangeTop = total < currentPerPage ? total : currentPerPage;
expanded = List.generate(_rangeTop, (index) => false);
usersTableSource = sourceFiltered.getRange(0, _rangeTop).toList();
} catch (e) {
print(e);
}
isLoading = false;
notifyListeners();
}
onSort(dynamic value){
isLoading = true;
notifyListeners();
sortColumn = value;
sortAscending = !sortAscending;
if (sortAscending) {
sourceFiltered.sort((a, b) =>
b["$sortColumn"].compareTo(a["$sortColumn"]));
} else {
sourceFiltered.sort((a, b) =>
a["$sortColumn"].compareTo(b["$sortColumn"]));
}
var _rangeTop = currentPerPage < sourceFiltered.length
? currentPerPage
: sourceFiltered.length;
usersTableSource = sourceFiltered.getRange(0, _rangeTop).toList();
searchKey = value;
isLoading = false;
notifyListeners();
}
onSelected(bool value, Map <String, dynamic> item){
print("$value $item ");
if (value) {
selecteds.add(item);
} else {
selecteds.removeAt(selecteds.indexOf(item));
}
notifyListeners();
}
onSelectAll(bool value){
if (value) {
selecteds = usersTableSource.map((entry) => entry).toList().cast();
} else {
selecteds.clear();
}
notifyListeners();
}
onChanged(int value){
currentPerPage = value;
currentPage = 1;
resetData();
notifyListeners();
}
previous(){
currentPage == 1
? null
: () {
var nextSet = currentPage - currentPerPage;
currentPage = nextSet > 1 ? nextSet : 1;
resetData(start: currentPage - 1);
};
notifyListeners();
}
next(){
currentPage + currentPerPage - 1 > total
? null
: () {
var nextSet = currentPage + currentPerPage;
currentPage = nextSet < total
? nextSet
: total - currentPerPage;
resetData(start: nextSet - 1);
};
notifyListeners();
}
TestTable.init() {
initializeData();
}
}
发布于 2022-06-03 11:10:21
它与loop range try to pass range as per data length see this post you will find you answer有关
var arr = [1, 2, 3];
for (var i=0; i < 4; i++) {
print(arr[i]);
}
检查数据长度的边界
https://stackoverflow.com/questions/72488351
复制相似问题