getter 'length' 没有为类型 'Future<List<Item>>' 定义
The getter 'length' isn't defined for the type 'Future<List<Item>>'
我正在 Flutter 中编写一种待办事项列表,启用了空安全。
我正在使用 sqflite 将待办事项列表存储在 sqlite 数据库中。
项目 class 如下:
class Item {
int? _id;
String? _name;
String? _notes;
String? _expiryDate;
int? _category;
int? _quantity;
Item(
this._id,
this._name,
this._notes,
this._expiryDate,
this._category,
this._quantity,
);
// names for db table and columns
String tableItems = 'items';
String colId = 'id';
String colName = 'name';
String colNotes = 'notes';
String colExpiryDate = 'expiryDate';
String colCategory = 'category';
String colQuantity = 'quantity';
// Getters
int? get id => _id;
String? get name => _name;
String? get notes => _notes;
String? get expiryDate => _expiryDate;
int? get category => _category;
int? get quantity => _quantity;
// Imports the Item details from a map
Item.fromMap(Map map) {
this._id = map[colId];
this._name = map[colName];
this._notes = map[colNotes];
this._expiryDate = map[colExpiryDate];
this._category = map[colCategory];
this._quantity = map[colQuantity];
}
// Converts a Item into a Map
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
map['id'] = _id;
map['name'] = _name;
map['notes'] = _notes;
map['expiryDate'] = _expiryDate;
map['category'] = _category;
map['quantity'] = _quantity;
return map;
}
// Implement toString to make it easier to see information about
// each dog when using the print statement.
@override
String toString() {
return 'Item{id: $_id, name: $_name, notes: $_notes, expiryDate: $_expiryDate, category: $_category, quantity: $_quantity}';
}
}
我有一个名为 items_controller 的 class,它充当项目 class 和 db_controller class 之间的中介。
这是 items_controller class:
import 'package:get/get.dart';
import 'package:<redacted>/model/item.dart';
import 'db_controller.dart';
class ItemsController extends GetxController {
// names for db table and columns
String tableItems = 'items';
String colId = 'id';
String colName = 'name';
String colNotes = 'notes';
String colExpiryDate = 'expiryDate';
String colCategory = 'category';
String colQuantity = 'quantity';
//TODO
void loadItem() {}
// function to retrieve all the items from the db
Future<List<Item>> loadAllItems() async {
final dbController = DBController();
final List<Map<String, dynamic>> itemsMaps =
await dbController.query(tableItems);
return List.generate(itemsMaps.length, (i) {
return Item.fromMap(itemsMaps[i]);
});
}
// function to add an item to the db
Future<int> addItem(Item item) async {
final dbController = DBController();
// add a new Item to the table and get the id
int id = await dbController.insertElement(tableItems, item);
return id;
}
//TODO
void updateItem() {}
//TODO
void deleteItem(int index) {}
}
鉴于此,从 list_builder(使用 ListView.builder 方法)我想构建一个列表,使用从数据库查询的项目列表的长度作为索引。
但是我有这个错误(如标题所示)
[![截图][1]][1]
[1]: https://i.stack.imgur.com/Z6VAh.png
我很确定我在调用 loadAllItems() 时得到的 Future 应该有一个 length 属性 因为它是一个列表,但我不确定,也许是因为它是 Future List?
请帮忙!
编辑
我已经实现了 FutureBuilder,但是我没有使用 .length 属性:
[![快照][2]][2]
[2]: https://i.stack.imgur.com/QswA0.png
如果我 运行 代码,我会得到以下错误:
Performing hot restart...
Syncing files to device AC2003...
lib/views/list_builder.dart:21:45: Error: The getter 'length' isn't defined for the class 'Object'.
- 'Object' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'length'.
itemCount: snapshot.data!.length,
^^^^^^
lib/views/list_builder.dart:16:20: Error: A non-null value must be returned since the return type 'Widget' doesn't allow null.
- 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../../flutter/packages/flutter/lib/src/widgets/framework.dart').
builder: (context, snapshot) {
^
Restarted application in 671ms.
你猜对了,因为是future,所以函数前要用await
,
你可以使用 FutureBuilder 并将函数传递给 future 参数,并通过快照访问列表,类似这样:
GetX<ItemController>(
builder: (controller) => FutureBuilder<List<Item>>(
future: controller.loadAllItems(),
builder: (context, snapshot) => snapshot.connectionState == ConnectionState.waiting
? CircularProgressIndicator()
: snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) => Container(
//data widget
),
)
: Container(
// empty widget
),
),
),
或者您可以在页面加载时调用该函数,并将项目保存在变量中(可能在控制器中,或者小部件本身),然后使用该变量获取 length
重要说明
确保未来的构建器 return 在每种情况下都是一个小部件,在您更新的问题中,有一个错误表明构建器 return 是空的
由于 loadAllItems() 调用是一个 Future,因此您需要将 ListBuilder 包装在 FutureBuilder 中。观看此视频了解更多信息。
基本上,您需要等待 Future 的结果,以便它成为一个列表。
FutureBuilder
是加载异步数据所需的,并在 ConnectionState
完成后获取列表
FutureBuilder(
future: controller.loadAllItems(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
int count = snapshot.data.length; // use this as itemCount in Listview
return ListView.Builder(); // write builder code here
}
}),
待读https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
我正在 Flutter 中编写一种待办事项列表,启用了空安全。 我正在使用 sqflite 将待办事项列表存储在 sqlite 数据库中。
项目 class 如下:
class Item {
int? _id;
String? _name;
String? _notes;
String? _expiryDate;
int? _category;
int? _quantity;
Item(
this._id,
this._name,
this._notes,
this._expiryDate,
this._category,
this._quantity,
);
// names for db table and columns
String tableItems = 'items';
String colId = 'id';
String colName = 'name';
String colNotes = 'notes';
String colExpiryDate = 'expiryDate';
String colCategory = 'category';
String colQuantity = 'quantity';
// Getters
int? get id => _id;
String? get name => _name;
String? get notes => _notes;
String? get expiryDate => _expiryDate;
int? get category => _category;
int? get quantity => _quantity;
// Imports the Item details from a map
Item.fromMap(Map map) {
this._id = map[colId];
this._name = map[colName];
this._notes = map[colNotes];
this._expiryDate = map[colExpiryDate];
this._category = map[colCategory];
this._quantity = map[colQuantity];
}
// Converts a Item into a Map
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
map['id'] = _id;
map['name'] = _name;
map['notes'] = _notes;
map['expiryDate'] = _expiryDate;
map['category'] = _category;
map['quantity'] = _quantity;
return map;
}
// Implement toString to make it easier to see information about
// each dog when using the print statement.
@override
String toString() {
return 'Item{id: $_id, name: $_name, notes: $_notes, expiryDate: $_expiryDate, category: $_category, quantity: $_quantity}';
}
}
我有一个名为 items_controller 的 class,它充当项目 class 和 db_controller class 之间的中介。 这是 items_controller class:
import 'package:get/get.dart';
import 'package:<redacted>/model/item.dart';
import 'db_controller.dart';
class ItemsController extends GetxController {
// names for db table and columns
String tableItems = 'items';
String colId = 'id';
String colName = 'name';
String colNotes = 'notes';
String colExpiryDate = 'expiryDate';
String colCategory = 'category';
String colQuantity = 'quantity';
//TODO
void loadItem() {}
// function to retrieve all the items from the db
Future<List<Item>> loadAllItems() async {
final dbController = DBController();
final List<Map<String, dynamic>> itemsMaps =
await dbController.query(tableItems);
return List.generate(itemsMaps.length, (i) {
return Item.fromMap(itemsMaps[i]);
});
}
// function to add an item to the db
Future<int> addItem(Item item) async {
final dbController = DBController();
// add a new Item to the table and get the id
int id = await dbController.insertElement(tableItems, item);
return id;
}
//TODO
void updateItem() {}
//TODO
void deleteItem(int index) {}
}
鉴于此,从 list_builder(使用 ListView.builder 方法)我想构建一个列表,使用从数据库查询的项目列表的长度作为索引。 但是我有这个错误(如标题所示) [![截图][1]][1] [1]: https://i.stack.imgur.com/Z6VAh.png
我很确定我在调用 loadAllItems() 时得到的 Future 应该有一个 length 属性 因为它是一个列表,但我不确定,也许是因为它是 Future List?
请帮忙!
编辑 我已经实现了 FutureBuilder,但是我没有使用 .length 属性: [![快照][2]][2] [2]: https://i.stack.imgur.com/QswA0.png
如果我 运行 代码,我会得到以下错误:
Performing hot restart...
Syncing files to device AC2003...
lib/views/list_builder.dart:21:45: Error: The getter 'length' isn't defined for the class 'Object'.
- 'Object' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'length'.
itemCount: snapshot.data!.length,
^^^^^^
lib/views/list_builder.dart:16:20: Error: A non-null value must be returned since the return type 'Widget' doesn't allow null.
- 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../../flutter/packages/flutter/lib/src/widgets/framework.dart').
builder: (context, snapshot) {
^
Restarted application in 671ms.
你猜对了,因为是future,所以函数前要用await
,
你可以使用 FutureBuilder 并将函数传递给 future 参数,并通过快照访问列表,类似这样:
GetX<ItemController>(
builder: (controller) => FutureBuilder<List<Item>>(
future: controller.loadAllItems(),
builder: (context, snapshot) => snapshot.connectionState == ConnectionState.waiting
? CircularProgressIndicator()
: snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) => Container(
//data widget
),
)
: Container(
// empty widget
),
),
),
或者您可以在页面加载时调用该函数,并将项目保存在变量中(可能在控制器中,或者小部件本身),然后使用该变量获取 length
重要说明
确保未来的构建器 return 在每种情况下都是一个小部件,在您更新的问题中,有一个错误表明构建器 return 是空的
由于 loadAllItems() 调用是一个 Future,因此您需要将 ListBuilder 包装在 FutureBuilder 中。观看此视频了解更多信息。
基本上,您需要等待 Future 的结果,以便它成为一个列表。
FutureBuilder
是加载异步数据所需的,并在 ConnectionState
完成后获取列表
FutureBuilder(
future: controller.loadAllItems(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
int count = snapshot.data.length; // use this as itemCount in Listview
return ListView.Builder(); // write builder code here
}
}),
待读https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html