Поставщик выставляет неверные значения с потоками - PullRequest
1 голос
/ 27 сентября 2019

Я использую Provider with для предоставления некоторых параметров виджетам в глубине дерева.Виджеты построены из 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 показывает идентификатор документа предыдущего документа

Как получить правильный идентификатор документа при обновлении потока?

Примечание. Мне известноЯ могу просто передать документ в качестве параметра.Однако мне нужен параметр в глубине дерева виджетов AnotherWidget

1 Ответ

1 голос
/ 28 сентября 2019

Похоже, именно поэтому был введен ProxyProvider

https://pub.dev/documentation/provider/latest/provider/ProxyProvider-class.html Цитируя важное примечание:

В отличие от параметра builder в Provider, builder может бытьзвонил не раз.Он будет вызываться один раз при монтировании виджета, а затем один раз, когда любой из InheritedWidget, от которого зависит ProxyProvider, испустит обновление

. Обертывание AnotherWidget с MultiProvider, содержащим ProxyProvider (как показано ниже), решает проблему

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