【问题标题】:Flutter product listing and details using FirestoreFlutter 产品列表和使用 Firestore 的详细信息
【发布时间】:2021-01-17 04:02:53
【问题描述】:

我正在努力为我遇到的这个问题找到明确的答案。我有两个屏幕,如下所示产品列表和产品详细信息。

第一个屏幕显示产品列表(Firebase 文档),当您点击某个项目时,它会将您带到产品详细信息屏幕。在产品显示屏幕上,您可以将产品标记为收藏,并有上一个和下一个产品的导航按钮。

我的问题是我不知道应该使用 Future 还是 Stream 来实现这一目标。

Future 使用问题 如果我使用Future<List<Product>>,我无法维护产品的书签状态,除非我每次为产品添加书签时都刷新产品列表。例如,如果说我为产品 2 添加了书签,然后导航到产品 3,然后返回到产品 2,则不会维护书签状态。

使用 Stream 的问题它解决了维护书签状态的问题,但是我不知道如何管理产品之间的导航(上一个/下一个)

我有以下代码可以使用 Stream

导航到下一个产品
class SearchResultsBloc implements BlocBase {
  SearchResultsBloc() {
    DatabaseService().Search().listen((data) => _inList.add(data));
  }

  final _listController = BehaviorSubject<List<Product>>();
  Stream<List<Product>> get outList => _listController.stream;
  Sink<List<Product>> get _inList => _listController.sink;

 Stream<Product> outDetails(String uid) {
    return outList.map<Product>((results) => results
        .firstWhere((product) => product.uid == uid, orElse: () => null));
  }

}

下面的这个方法用于检索下一个产品,但有人建议我不应该这样做,因为流可能会改变,而且我不知道如果我可以禁用 导航按钮'正在查看第一个产品或禁用 Next > 如果我正在查看最后一个产品。

 Stream<Product> nextProduct(String uid) {
    var index = outList
        .map<int>(
            (results) => results.indexWhere((product) => product.uid == uid))
        .first
        .asStream();

    int nextIndex;
    index.listen((index) {
      nextIndex = index + 1;
    });

    return outList.map<Product>((results) => results.elementAt(nextIndex));
  }

【问题讨论】:

  • 您是否出于特定原因使用 Streams?如果是不会实时变化的数据,为什么不直接使用普通查询呢?
  • 使用 Streams 实时更新项目。如果我使用 Future 并对某个项目进行更改,我将需要刷新产品列表。
  • 那么你只需要在Firestore上监听那个特定路径的数据流。

标签: firebase flutter dart google-cloud-firestore state-management


【解决方案1】:

使用StreamBuilder 进行实时更改

StreamBuilder<QuerySnapshot>(
      stream:  FirebaseFirestore.instance.collection(Your collection).snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }

        return new ListView(
          children: snapshot.data.documents.map((DocumentSnapshot document) {
            return new ListTile(
              title: new Text(document.data()[key]),
              subtitle: new Text(document.data()[key]),
            );
          }).toList(),
        );
      },
    );

在导航到下一页时,您必须传递 snapshot.data,因此如果后端有任何更改,它将自动影响 UI。

您的 outDetails 方法似乎没问题,但是当用户点击特定的 listTile 或您的自定义小部件时,您只需传递 snapshot.data.document.data()

【讨论】:

  • 我已经这样做了,我想知道如何根据当前正在查看的项目管理上一个/下一个链接。
猜你喜欢
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
相关资源
最近更新 更多