提供者使用 Streams 公开不正确的值

Posted

技术标签:

【中文标题】提供者使用 Streams 公开不正确的值【英文标题】:Provider exposes incorrect values with Streams 【发布时间】:2020-01-28 04:10:20 【问题描述】:

我正在使用 Provider 向树深处的 Widget 公开一些参数。小部件是从 Streambuilder 构建的,即 Firebase 文档

但是,Provider 似乎没有公开正确的值

我的代码的一个非常简化的版本:

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

class Parameters 
  Parameters(this.documentId);
  final String documentId;


class Widget1 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return StreamBuilder<QuerySnapshot>(
        stream: mystream, //Query the Firebase for a bunch of Documents
        builder: (context, snapshot) 
          if (snapshot.hasError) 
            return Text('Error processing data feed');
          
          switch (snapshot.connectionState) 
            case ConnectionState.waiting:
              
                return CircularProgressIndicator();
              
              break;
            default:
              
                var _messages = snapshot.data.documents;

                return ListView.builder(
                    itemCount: _messages.length,
                    itemBuilder: (context, index) 
                      return Provider<Parameters>(
                          builder: (context) =>
                              Parameters(_messages[index].documentID),
                          child: AnotherWidget());
                    );
              
          
        );
  


class AnotherWidget extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    Parameters param = Provider.of<Parameters>(context);
    return Text(param.documentId);
  

第一次构建小部件时,这非常有效。但是,当插入新文档时,AnotherWidget 会显示上一个文档的文档 ID

更新流时如何获取正确的文档 ID?

注意:我知道我可以简单地将文档作为参数传递。但是我需要AnotherWidget的小部件树深处的参数

【问题讨论】:

【参考方案1】:

看起来这正是引入 ProxyProvider 的原因

https://pub.dev/documentation/provider/latest/provider/ProxyProvider-class.html 引用重要说明:

相对于Provider的builder参数,builder可以被多次调用。它会在挂载小部件时调用一次,然后在 ProxyProvider 所依赖的任何 InheritedWidget 发出更新时调用一次

通过使用包含ProxyProvider的MultiProvider包装AnotherWidget(如下)解决了这个问题

child: MultiProvider(
                        providers: [
                            Provider.value(value: _messages[index].documentID),
                            ProxyProvider<String, Parameters>(
                              builder: (context, documentId, parameters) => Parameters(documentId),
                            ),
                          ],
                          child: AnotherWidget()));

【讨论】:

以上是关于提供者使用 Streams 公开不正确的值的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 使用带有枚举的选择器和提供的值并返回正确的 tag()

Ada - (Streams) 如何在事先不知道字符串长度的情况下正确调用 String'Read()

C# 8中的Async Streams

如何在提供者的值中传递数组和 setArray(React、Typescript、Context)

在 RestAssured jsonPathEvaluator 中,没有为双值提供正确的值

浅谈kafka streams