Flutter: создание динамически обновляемого DataTable с несколькими коллекциями потоков из Firestore - PullRequest
2 голосов
/ 17 февраля 2020

Итак, я (пытаюсь) создать DataTable для динамического отображения группы пакетов (таких как пакеты Amazon или UPS) на основе данных Firestore. Сложность заключается в следующем: мои данные хранятся в нескольких коллекциях в базе данных, в «очереди», «в доме» и «учениках».

Я создал версию того, что я хочу, используя ListView.builder и ListViewTiles. В настоящее время он работает отлично, отображая новые плитки по мере добавления новых данных в очередь. Вместо использования ListView я хотел бы отобразить все данные в таблице (DataTable); однако у меня возникли проблемы с тем, чтобы уместить то, что у меня уже есть (FutureBuilders и StreamBuilders), таким образом, чтобы это работало с DataTable.

У меня также есть заполнитель DataTable, который отображает несколько фиктивных пакетов из предопределенных список точно так, как я хочу.

Я провел исследование использования провайдера для предоставления списка перестройки для виджета DataTable ... Но я не могу соединить точки при попытке чтения из нескольких коллекций одновременно.

Вот код для моего ListView ...

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class QueueDisplay extends StatefulWidget {
  @override
  _QueueDisplayState createState() => _QueueDisplayState();
}

class _QueueDisplayState extends State<QueueDisplay> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: StreamBuilder(
        stream: Firestore.instance.collection('queue').snapshots(),
        builder:(context, snapshot){
          if (!snapshot.hasData){
            return (Center(child: CircularProgressIndicator()));
          } else {
            return ListView.builder(
              itemCount: snapshot.data.documents.length,
              itemBuilder: (context, index) {
                DocumentSnapshot queueDoc = snapshot.data.documents[index];
                return Column(
                  children: <Widget>[
                    FutureBuilder(
                      future: Firestore.instance.collection('students').document('${queueDoc.data['owner']}').get(),
                      builder: (BuildContext context, AsyncSnapshot studentSnap) {
                        return FutureBuilder(
                          future: Firestore.instance.collection('inhouse').where('owner', isEqualTo: queueDoc.data['owner']).getDocuments(),
                          builder: (BuildContext context, AsyncSnapshot packSnap) {
                            if (packSnap.hasData){
                              if(packSnap.data!=null){
                                return ListTile(
                                    title: Row(
                                      children: <Widget>[
                                        Text('${queueDoc.data['owner']}' + '     '),
                                        Text('${studentSnap.data['name']}' + '     '),
                                        Text('${packSnap.data.documents[0].documentID}'),
                                      ],
                                    )
                                );
                              }
                            } else {
                              return Center(child: CircularProgressIndicator());
                            }
                            return Center(child: CircularProgressIndicator());
                          },
                        );
                      },
                    )
                  ],
                );
              },
            );
          }
        },
      ),
    );
  }
}

Функционирование Снимок экрана ListView

А вот код для заполнителя DataTable ...

class QueueTable extends StatefulWidget {
  @override
  _QueueTableState createState() => _QueueTableState();
}

class _QueueTableState extends State<QueueTable> {
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Container(
        //color: Colors.grey[200],
        child: DataTable(
          // Table Displaying Queued Packages
            columnSpacing: 8,
            columns: [
              DataColumn(label: Text("Name"),numeric: false, onSort: (i, b) {}),
              DataColumn(label: Text("Location"),numeric: false, onSort: (i, b) {}),
              DataColumn(label: Text("Tracking"),numeric: false, onSort: (i, b) {}),
              DataColumn(label: Text("Carrier"),numeric: false, onSort: (i, b) {}),
              DataColumn(label: Text("Notes"),numeric: false, onSort: (i, b) {}),
              DataColumn(label: Text("Received"),numeric: false, onSort: (i, b) {}),
            ],
            rows: packages.map((package) => DataRow(
                onSelectChanged: (b) {},
                cells: [
                  DataCell(Text(package.owner.name), onTap: (){}),
                  DataCell(Text(package.location), onTap: (){}),
                  DataCell(Text(package.tracking)),
                  DataCell(Text(package.carrier)),
                  DataCell(Text(package.notes), onTap: (){}),
                  DataCell(Text(package.rDate)),
            ])).toList()
        ),
      ),
    );
  }
}

Student adam =
    Student('0000004028', 'Adam G', 'adamg@email.net');
var packages = [
  Package(adam, 'Large', 'USPS', '1/15/2020', '123456', 'Great Dude!'),
  Package(adam, 'Small', 'UPS', '1/16/2020', '1234567', 'Great Guy!'),
  Package(adam, 'Medium', 'FedEx', '1/18/2020', '12345678', 'Great Bro!'),
  Package(adam, 'Floor', 'Amazon', '1/5/2020', '123456789', 'Great Person!'),
];

Скриншот заполнителя DataTable

Оба предоставленных фрагмента кода должны работать нормально; Я просто не могу объединить их в рабочую динамику c DataTable ...

Есть предложения? Спасибо!

Обновление:

Итак, вот моя ближайшая попытка до сих пор ...

Я создал поток List и использовал StreamProvider для предоставить поток виджету, создающему DataTable.

database.dart

Поставщик, который возвращает только нулевые пакеты

It кажется, что будет работать; если бы только я мог получить _queueListFromSnapshot, чтобы вернуть правильное значение для пакета p. Из-за вложенных операторов Future.then () {} я пока не могу понять, как вернуть правильное значение. (Показано в комментариях database.dart)

Обновление 2:

Вот чуть лучше попробуйте с использованием async / await. Это требует, чтобы я изменил тип возвращаемого значения функции, что вызывает несоответствие дальше, потому что я все еще хочу вернуть заполненный список в StreamProvider ... правильно?

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