好的,我的任务是,1.从Firestore下载记录,2.将其处理为状态变量3.将数据注入小部件。
我曾尝试通过在initState中下载内容来做到这一点,使它成为Async,但是然后在Firestore下载完成之前调用了build方法,我没有为小部件准备的信息,它崩溃了。
我读到,当预期在布局后的小部件会发生变化时,我应该为小部件使用Builder包装器。这使我想到了:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Job details")), // TODO might have to modify to accomodate edits
body: _buildBody(context, widget.job.country, widget.job.area, widget.job.jobDetailedId, widget.job),
);
}
因此,我使用构建器的上下文调用buildBody,似乎我无法访问我的this.job类对象(为什么?!),因此我传递了一些关键参数来获取Firestore记录。
_buildBody的目的是下载Firestore记录,而无需使用ASYNC等待。但是它从不执行
以外的任何代码。then((jobrecord {
Widget _buildBody(BuildContext context, String countryCode, String area, String jobDetailedId) {
Job detailedJob;
Firestore.instance.collection("$countryCode/$area/JobsDetailed").document(jobDetailedId).get().then((jobRecord) {
return Builder(builder: (BuildContext context) {
if(jobRecord == null) {
return Text("Document doesn't exist");
}
else {
detailedJob = Job.fromSnapshot(jobRecord);
detailedJob.jobDetailedId = jobRecord.documentID;
return _screenBuild(context, detailedJob);
}
});
});
}
Widget _screenBuild(BuildContext context, Job detailedJob) {
return Text(detailedJob.description);
}
我以为,那么当Firestore返回文档时,它将触发,但不会触发。
这是解决问题的最好,最清晰的方法吗?使用Future会更好吗?还是Asnc从initState()等待,然后使用setState()?
此代码段应完成工作。
Widget _buildBody(BuildContext context, String countryCode, String area, String jobDetailedId) {
Job detailedJob;
return StreamBuilder<DocumentSnapShot>(
stream: Firestore.instance.collection("$countryCode/$area/JobsDetailed").document(jobDetailedId).snapshots(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
var jobRecord = snapshot.data.data; // contains document fields
if(jobRecord == null) {
return Text("Document doesn't exist");
}
else {
detailedJob.jobDetailedId = jobRecord.documentID;
return _screenBuild(context, detailedJob);
}
}
});
}