Флаттер: Как обновить виджеты, когда их содержимое поступает из Google Firestore? - PullRequest
0 голосов
/ 09 апреля 2020

ОК, так что моя миссия такова: 1. загрузить запись из Firestore, 2. обработать ее в переменные состояния 3. внедрить данные в виджеты.

Я пытался сделать это, загрузив материал в initState, я сделал это Asyn c, однако метод сборки был вызван до завершения загрузки Firestore, у меня не было готовой информации для виджетов, и она вылетела.

Я читал, что когда ожидается изменение виджета после того, как выложено, я должен использовать оболочку 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 с контекстом для Builder, похоже, я теряю доступ к своему объекту класса this.job (почему ?!), поэтому я передаю некоторые важные параметры в для получения записи Firestore.

Целью _buildBody является загрузка записи Firestore без использования ASYN C await. Но он никогда не выполняет какой-либо код за пределами

.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? Или Asn c ждут от initState (), а затем использовать setState ()?

1 Ответ

2 голосов
/ 09 апреля 2020

Этот фрагмент должен выполнить всю работу.

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 = Job.fromSnapshot(snapshot.data);
                detailedJob.jobDetailedId = jobRecord.documentID;
                return _screenBuild(context, detailedJob);
              }
            }
          });
}
...