提供程序使用流公开不正确的值

时间:2019-09-27 20:53:54

标签: flutter google-cloud-firestore provider

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

但是,提供者似乎没有公开正确的值

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

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的widget树的最深处

1 个答案:

答案 0 :(得分: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()));