无法使用 Getx Statemanagement [更新] 从 Cloud firestore 检索地图流列表以进行颤动
Can't retrieve a Stream List of map from cloud firestore for flutter using Getx Statemanagement [Updated]
我正在尝试从云 Firestore 中检索 NewsModel 的流列表,但最终失败了。代码和图片如下
我有一个集合 'news' > 文档 'USA' > 字段列表。 // 列表是一个包含地图列表的数组。我想检索此列表。
如何从 firebase 检索数据、存储在模型对象中并将模型用于 UI?
错误:
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling: [](0)
代码如下:
型号:
class NewsModel {
String title, titleImage, brief;
List aList;
NewsModel({this.title, this.titleImage, this.brief, this.aList});
factory NewsModel.fromMap(dynamic fieldData) {
return NewsModel(
title: fieldData['title'],
titleImage: fieldData['titleImage'],
brief: fieldData['brief'],
aList: fieldData['mediaDescList']);
}
}
控制器:
class Controller extends GetxController {
// onInit
@override
void onInit() {
finalNewsModel.bindStream(streamDemo());
fetchDocs();
super.onInit();
}
//
Rxn<List<NewsModel>> finalNewsModel = Rxn<List<NewsModel>>();
//
List<NewsModel> get newsModelList => finalNewsModel.value;
//
Stream<List<NewsModel>> streamDemo() {
return FirebaseFirestore.instance
.collection('news')
.doc('USA')
.snapshots()
.map((ds) {
var mapData = ds.data();
List mapList = mapData['list'];
List<NewsModel> newsModelList = [];
mapList.forEach((element) {
newsModelList.add(NewsModel.fromMap(element));
});
return newsModelList;
});
}
}
UI:
class HomeBody extends StatefulWidget {
@override
_HomeBodyState createState() => _HomeBodyState();
}
class _HomeBodyState extends State<HomeBody> {
//
final _controller = Get.put(Controller());
//
NewsModel _newsModel = NewsModel();
@override
Widget build(BuildContext context) {
return Container(
child: GetBuilder<Controller>(builder: (_controller) {
if (_controller.newsModelList == null) {
return Text('Loading');
} else if (_controller.newsModelList.isEmpty) {
return Text('Empty List');
} else {
return ListView.builder(
itemCount: _controller.newsModelList.length,
itemBuilder: (context, index) {
return MyContainer(
title: _newsModel.title[index],
titleImage: _newsModel.titleImage[index],
);
},
);
}
}),
);
}
}
错误 1:
The getter 'length' was called on null.
错误来自您下面的空检查:
if (_controller.newsModelList.length == null) {
return Text('Loading');
}
您正在检查列表的长度是否为 null
,但列表本身为空,因此您在 null
上调用 .length
。
这就是错误提示的原因:
The getter 'length' was called on null.
解法:
您应该检查列表本身是否为空,如下所示:
if (_controller.newsModelList == null) {
return Text('Loading');
}
现在如果你想检查列表是否为空,你必须先确保列表不是null
,然后你可以在列表上调用.isEmpty()
。
然后您可以添加现有的 else 语句以显示 MyContainer
个小部件的列表。
错误2:
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling:
此错误是因为您试图获取空对象的值。
它出现在下面的行中:
title: _newsModel.title[index],
titleImage: _newsModel.titleImage[index],
这是因为 _newsModel.title
和 _newsModel.titleImage
为空,因为您在没有提供参数的情况下创建了 _newsModel
对象。
解法:
解决方案是从您的 build
方法中删除下面这一行:
NewsModel _newsModel = NewsModel();
然后您可以从 _controller.newsModelList
列表中获取您的 _newModel
变量。
包含这两种解决方案的新 UI 代码应更新为以下代码块:
class HomeBody extends StatefulWidget {
@override
_HomeBodyState createState() => _HomeBodyState();
}
class _HomeBodyState extends State<HomeBody> {
//
final _controller = Get.put(Controller());
@override
Widget build(BuildContext context) {
return Container(
child: Obx(() {
if (_controller.newsModelList == null) {
return Text('Loading');
} else if (_controller.newsModelList.isEmpty) {
return Text('Empty List');
} else {
return ListView.builder(
itemCount: _controller.newsModelList.length,
itemBuilder: (context, index) {
final NewsModel _newsModel = _controller.newsModelList[index];
return MyContainer(
title: _newsModel.title,
titleImage: _newsModel.titleImage,
index: index,
);
},
);
}
}),
);
}
你应该初始化一个值给 Rxn
Rxn<List<NewsModel>> finalNewsModel = Rxn<List<NewsModel>>([]);
//change stream like this
Stream<List<NewsModel>> streamDemo() {
return FirebaseFirestore.instance
.collection('news')
.doc('USA')
.snapshots()
.map((ds) {
var mapData = ds.data();
List mapList = mapData['list'];
List<NewsModel> newsModelList = [];
mapList.forEach((element) {
newsModelList.add(NewsModel.fromMap(element));
});
return newsModelList;
});
}
使用 GetX 生成器或 Obx
class HomeBody extends StatefulWidget {
@override
_HomeBodyState createState() => _HomeBodyState();
}
class _HomeBodyState extends State<HomeBody> {
//
final Controller _controller = Get.put<Controller>(Controller());
//
@override
Widget build(BuildContext context) {
return Container(
child: Obx((){
if (_controller.newsModelList == null) {
return Text('Loading');
} else if (_controller.newsModelList.isEmpty) {
return Text('Empty List');
} else {
return ListView.builder(
itemCount: _controller.newsModelList.length,
itemBuilder: (context, index) {
return MyContainer(
title: _newsModel.title[index],
titleImage: _newsModel.titleImage[index],
);
},
);
}
}),
);
}
}
我正在尝试从云 Firestore 中检索 NewsModel 的流列表,但最终失败了。代码和图片如下
我有一个集合 'news' > 文档 'USA' > 字段列表。 // 列表是一个包含地图列表的数组。我想检索此列表。
如何从 firebase 检索数据、存储在模型对象中并将模型用于 UI?
错误:
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling: [](0)
代码如下:
型号:
class NewsModel {
String title, titleImage, brief;
List aList;
NewsModel({this.title, this.titleImage, this.brief, this.aList});
factory NewsModel.fromMap(dynamic fieldData) {
return NewsModel(
title: fieldData['title'],
titleImage: fieldData['titleImage'],
brief: fieldData['brief'],
aList: fieldData['mediaDescList']);
}
}
控制器:
class Controller extends GetxController {
// onInit
@override
void onInit() {
finalNewsModel.bindStream(streamDemo());
fetchDocs();
super.onInit();
}
//
Rxn<List<NewsModel>> finalNewsModel = Rxn<List<NewsModel>>();
//
List<NewsModel> get newsModelList => finalNewsModel.value;
//
Stream<List<NewsModel>> streamDemo() {
return FirebaseFirestore.instance
.collection('news')
.doc('USA')
.snapshots()
.map((ds) {
var mapData = ds.data();
List mapList = mapData['list'];
List<NewsModel> newsModelList = [];
mapList.forEach((element) {
newsModelList.add(NewsModel.fromMap(element));
});
return newsModelList;
});
}
}
UI:
class HomeBody extends StatefulWidget {
@override
_HomeBodyState createState() => _HomeBodyState();
}
class _HomeBodyState extends State<HomeBody> {
//
final _controller = Get.put(Controller());
//
NewsModel _newsModel = NewsModel();
@override
Widget build(BuildContext context) {
return Container(
child: GetBuilder<Controller>(builder: (_controller) {
if (_controller.newsModelList == null) {
return Text('Loading');
} else if (_controller.newsModelList.isEmpty) {
return Text('Empty List');
} else {
return ListView.builder(
itemCount: _controller.newsModelList.length,
itemBuilder: (context, index) {
return MyContainer(
title: _newsModel.title[index],
titleImage: _newsModel.titleImage[index],
);
},
);
}
}),
);
}
}
错误 1:
The getter 'length' was called on null.
错误来自您下面的空检查:
if (_controller.newsModelList.length == null) {
return Text('Loading');
}
您正在检查列表的长度是否为 null
,但列表本身为空,因此您在 null
上调用 .length
。
这就是错误提示的原因:
The getter 'length' was called on null.
解法:
您应该检查列表本身是否为空,如下所示:
if (_controller.newsModelList == null) {
return Text('Loading');
}
现在如果你想检查列表是否为空,你必须先确保列表不是null
,然后你可以在列表上调用.isEmpty()
。
然后您可以添加现有的 else 语句以显示 MyContainer
个小部件的列表。
错误2:
The following NoSuchMethodError was thrown building: The method '[]' was called on null. Receiver: null Tried calling:
此错误是因为您试图获取空对象的值。 它出现在下面的行中:
title: _newsModel.title[index],
titleImage: _newsModel.titleImage[index],
这是因为 _newsModel.title
和 _newsModel.titleImage
为空,因为您在没有提供参数的情况下创建了 _newsModel
对象。
解法:
解决方案是从您的 build
方法中删除下面这一行:
NewsModel _newsModel = NewsModel();
然后您可以从 _controller.newsModelList
列表中获取您的 _newModel
变量。
包含这两种解决方案的新 UI 代码应更新为以下代码块:
class HomeBody extends StatefulWidget {
@override
_HomeBodyState createState() => _HomeBodyState();
}
class _HomeBodyState extends State<HomeBody> {
//
final _controller = Get.put(Controller());
@override
Widget build(BuildContext context) {
return Container(
child: Obx(() {
if (_controller.newsModelList == null) {
return Text('Loading');
} else if (_controller.newsModelList.isEmpty) {
return Text('Empty List');
} else {
return ListView.builder(
itemCount: _controller.newsModelList.length,
itemBuilder: (context, index) {
final NewsModel _newsModel = _controller.newsModelList[index];
return MyContainer(
title: _newsModel.title,
titleImage: _newsModel.titleImage,
index: index,
);
},
);
}
}),
);
}
你应该初始化一个值给 Rxn
Rxn<List<NewsModel>> finalNewsModel = Rxn<List<NewsModel>>([]);
//change stream like this
Stream<List<NewsModel>> streamDemo() {
return FirebaseFirestore.instance
.collection('news')
.doc('USA')
.snapshots()
.map((ds) {
var mapData = ds.data();
List mapList = mapData['list'];
List<NewsModel> newsModelList = [];
mapList.forEach((element) {
newsModelList.add(NewsModel.fromMap(element));
});
return newsModelList;
});
}
使用 GetX 生成器或 Obx
class HomeBody extends StatefulWidget {
@override
_HomeBodyState createState() => _HomeBodyState();
}
class _HomeBodyState extends State<HomeBody> {
//
final Controller _controller = Get.put<Controller>(Controller());
//
@override
Widget build(BuildContext context) {
return Container(
child: Obx((){
if (_controller.newsModelList == null) {
return Text('Loading');
} else if (_controller.newsModelList.isEmpty) {
return Text('Empty List');
} else {
return ListView.builder(
itemCount: _controller.newsModelList.length,
itemBuilder: (context, index) {
return MyContainer(
title: _newsModel.title[index],
titleImage: _newsModel.titleImage[index],
);
},
);
}
}),
);
}
}