Как показать результат асинхронной функции в виде списка - PullRequest
0 голосов
/ 20 октября 2018

Я пытаюсь создать просмотр списка, чтобы показать некоторые события с их соответствующими пользователями, но список создается до завершения метода, а затем приводит к пустому списку ...

Я пробовал это, но проблемавсе еще продолжается:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:project/Methods.dart';
import 'package:project/Views/CadastroUsuario.dart';
import 'package:project/classes/eventos.dart';

class ListagemEventos extends StatefulWidget {
  @override
  ListagemEventosState createState() => new ListagemEventosState();
}

class ListagemEventosState extends State<ListagemEventos> {
  @override
  void initState() {
    super.initState();
  }

  Future<List<Event>> getEvents() async {
    CollectionReference eventsDoc = Firestore.instance.collection("events");
    return await eventsDoc.getDocuments().then((snapshot) { 
       List<Event> events = new List<Event>();
       snapshot.documents.forEach((doc) async {
          Event event = new Event();  
          String id;         

          event.description      = doc["description"];
          event.city             = doc["city"];
          event.state            = doc["state"];
          event.location         = doc["location"];
          event.date             = doc["date"];
          event.placesAvailable  = doc["placesAvailable"];
          event.totalPlaces      = doc["placesTotal"];

          id = doc["userId"];
          event.owner = new UserOwner();

          CollectionReference eventsDoc = Firestore.instance.collection("users");
          event.owner = await eventsDoc.document(id).get().then((doc) {
            UserOwner userOwner = new UserOwner();
            userOwner.userid = id;
            userOwner.name   = doc["name"];
            userOwner.phone  = doc["phone"];
            userOwner.email  = doc["email"];
            userOwner.city   = doc["city"];
            userOwner.state  = doc["state"];
            userOwner.photo  = doc["photo"];

            event.owner = userOwner;

            return userOwner;
          });

          events.add(event);
        });

        return events;
    });
  }

  Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
    List<Event> events = snapshot.data;

    return new ListView.builder(
      itemCount: events.length,
      itemBuilder: (BuildContext context, int index){
        return item(events[index]);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Eventos'), 
      ),
      body: new FutureBuilder(
        future: getEvents(),
        builder: (BuildContext context, AsyncSnapshot snapshot){
          switch (snapshot.connectionState) {
            case ConnectionState.waiting: return new Text("Loading...");
            default: 
              if(snapshot.hasError)
                return new Text("Erro: ${snapshot.error}");
              else
                return createListView(context, snapshot);
          }
        },
      ),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'Novo',
        child: new Icon(Icons.add),
        onPressed: () async {
          Navigation navigation = new Navigation();
          navigation.navigaTo(context, CadastroUsuario());
          },
      ),
    );
  }

  Widget item(Event event) {
    return new Card(
      elevation: 4.0,
      child: new Column(
        children: <Widget>[
          new Row(
            children: <Widget>[
              new Column(
                children: <Widget>[
                  new Text(event.owner.name.toString(),
                    style: TextStyle(fontSize: 20.0),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Column(
                children: <Widget>[
                ],
              )
            ],
          ),
          new Container(
            color: Colors.blue,
            height: 150.0,
          ),
          new Row(
            children: <Widget>[
              new Row(
                children: <Widget>[
                  new Text(event.description.toString(), 
                    style: TextStyle(fontSize: 20.0),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Row(
                children: <Widget>[
                  new Text(event.location.toString(), 
                    style: TextStyle(color: Colors.grey[350]),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Row(
                children: <Widget>[
                  new Text(event.city.toString() +' - '+ event.state.toString(), 
                    style: TextStyle(color: Colors.grey[350]),
                    overflow: TextOverflow.ellipsis,),
                ],
              )
            ]
          )          
        ],
      )
    );
  }
}

Как я могу решить эту проблему?
Есть ли другой способ сделать это?

PS: Я был бы признателен, если бы вы могли привести мне пример тоже

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Наконец-то я нашел способ ... Я инициализирую слушателя в initState, и когда меняются изменения в моем пожарном хранилище, я использую setState, чтобы восстановить свой обычный просмотр списка

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:project/Methods.dart';
import 'package:project/Views/CadastroUsuario.dart';
import 'package:project/classes/eventos.dart';

class ListagemEventos extends StatefulWidget {
  @override
  ListagemEventosState createState() => new ListagemEventosState();
}

class ListagemEventosState extends State<ListagemEventos> {
  List<Event> _events;

  @override
  void initState() {
    super.initState();
    _events = new List<Event>();
    Firestore.instance.collection("events").snapshots().listen((snapshot){
      getEvents(snapshot);
    });
  }

  void getEvents(QuerySnapshot eventsDoc) {
    List<Event> events = new List<Event>();

    eventsDoc.documents.forEach((doc) async {
      Event event = new Event();  
      String id;         

      event.description      = doc["description"];
      event.city             = doc["city"];
      event.state            = doc["state"];
      event.location         = doc["location"];
      event.date             = doc["date"];
      event.placesAvailable  = doc["placesAvailable"];
      event.totalPlaces      = doc["placesTotal"];

      id = doc["userId"];
      event.owner = new UserOwner();

      CollectionReference eventsDoc = Firestore.instance.collection("users");
      event.owner = await eventsDoc.document(id).get().then((doc) {
        UserOwner userOwner = new UserOwner();
        userOwner.userid = id;
        userOwner.name   = doc["name"];
        userOwner.phone  = doc["phone"];
        userOwner.email  = doc["email"];
        userOwner.city   = doc["city"];
        userOwner.state  = doc["state"];
        userOwner.photo  = doc["photo"];

        event.owner = userOwner;

        return userOwner;
      });

      events.add(event);
      setState(() {
        _events = events;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Eventos'), 
      ),
      body: 
      _events.length == 0
      ?
        new Center(child: new CircularProgressIndicator())
      :
        new ListView.builder(
          itemCount: _events.length,
          itemBuilder: (BuildContext context, int index){
            return item(_events[index]);
          }
        )
      ,floatingActionButton: new FloatingActionButton(
        tooltip: 'Novo',
        child: new Icon(Icons.add),
        onPressed: () async {
          Navigation navigation = new Navigation();
          navigation.navigaTo(context, CadastroUsuario());
          },
      ),
    );
  }

  Widget item(Event event) {
    return new Card(
      elevation: 4.0,
      child: new Column(
        children: <Widget>[
          new Row(
            children: <Widget>[
              new Column(
                children: <Widget>[
                  new Text(event.owner.name.toString(),
                    style: TextStyle(fontSize: 20.0),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Column(
                children: <Widget>[
                ],
              )
            ],
          ),
          new Container(
            color: Colors.blue,
            height: 150.0,
          ),
          new Row(
            children: <Widget>[
              new Row(
                children: <Widget>[
                  new Text(event.description.toString(), 
                    style: TextStyle(fontSize: 20.0),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Row(
                children: <Widget>[
                  new Text(event.location.toString(), 
                    style: TextStyle(color: Colors.grey[350]),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Row(
                children: <Widget>[
                  new Text(event.city.toString() +' - '+ event.state.toString(), 
                    style: TextStyle(color: Colors.grey[350]),
                    overflow: TextOverflow.ellipsis,),
                ],
              )
            ]
          )          
        ],
      )
    );
  }
  }
0 голосов
/ 20 октября 2018

Поскольку я не могу запустить ваш код, потому что он имеет другие зависимости, я постараюсь помочь вам как можно лучше, не тестируя его.

Одна вещь, которую нужно помнить о флаттере (которая сделала его намного проще для меняЭто означает, что представление никогда не обновляется, пока вы не вызовете этот метод.

this.setState(() {});

Поэтому, когда вы на 100% уверены, что данные загружены, вызывайте эту функцию.Это восстановит ваше представление и снова вызовет функцию сборки, которая должна обновить ваше представление.Я надеюсь, что это поможет вам.

Зная это, вы можете сделать свой код намного проще.Вы можете просто сделать просмотр списка, который имеет переменную «Дети».Заполните эту переменную в вашей асинхронной функции и снова вызовите setState.Это заполнит список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...