首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态更改docId时不更新流

动态更改docId时不更新流
EN

Stack Overflow用户
提问于 2021-05-23 13:01:35
回答 2查看 629关注 0票数 0

当动态更新streamDemo()的值时,mainDocId ()不会更新doc('$mainDocId')的值。我希望在动态更改文档Id时更新小部件HomeBody(),以便按照用户选择的文档检索数据。

我用getx做SM。我尝试用update()方法更新该值,但不起作用。

代码如下。

主计长:

代码语言:javascript
复制
class Controller extends GetxController {

  // onInit
  @override
  void onInit() {
    finalNewsModel.bindStream(streamDemo());
    super.onInit();
  }

 
  // list of document ids.
  List docIdList = [
    'USA',
    'New York',
    'Canada',
  ];

  //
  RxString mainDocId = 'USA'.obs;

  // method to change document id based on docId index.
  changeDocId(int index) {
    mainDocId(docIdList[index]);
  }

  //
  Rxn<List<NewsModel>> finalNewsModel = Rxn<List<NewsModel>>();

  //
  List<NewsModel> get newsModelList => finalNewsModel.value;

  //
  Stream<List<NewsModel>> streamDemo() {
    return FirebaseFirestore.instance
        .collection('news')
        .doc('$mainDocId')
        .snapshots()
        .map((ds) {
      var mapData = ds.data();
      List mapList = mapData['list'];
      List<NewsModel> modelList = [];
      mapList.forEach((element) {
        modelList.add(NewsModel.fromMap(element));
      });
      return modelList;
    });
  }
}

// UI

代码语言:javascript
复制
class HomeBody extends StatefulWidget {
  @override
  _HomeBodyState createState() => _HomeBodyState();
}

class _HomeBodyState extends State<HomeBody> {
//
  final Controller _controller = Get.put<Controller>(Controller());

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Obx(() {
        if (_controller.newsModelList == null) {
          return Center(
              child: Text(
            'Please try later!',
          ));
        } else if (_controller.newsModelList.isEmpty) {
          return Text('Empty List');
        } else {
          return ListView.builder(
            itemCount: _controller.newsModelList.length,
            itemBuilder: (context, index) {
              final NewsModel _newsModel = _controller.newsModelList[index];
              return MyContainer(
                title: _newsModel.title,
                titleImage: _newsModel.titleImage,
                index: index,
              );
            },
          );
        }
      }),
    );
  }
}

BottomNavBar:

代码语言:javascript
复制
bottomNavigationBar: Container(
        color: Colors.grey[300],
        height: 60.0,
        child: Padding(
          padding: EdgeInsets.all(8.0),
          child: GetBuilder<Controller>(
            builder: (context) => ListView.builder(
              shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              itemCount: _controller.docIdList.length,
              itemBuilder: (context, index) {
                return FavCategoryTags(
                  tagName: _controller.docIdList[index],
                  onpress: () =>_controller.changeDocId(index),
                );
              },
            ),
          ),
        ),
      ),

型号:

代码语言:javascript
复制
class NewsModel {
  String title, titleImage, brief, source;
  List aList;

  NewsModel({this.title, this.titleImage, this.brief, this.aList, this.source});

  factory NewsModel.fromMap(dynamic fieldData) {
    return NewsModel(
      title: fieldData['title'],
      titleImage: fieldData['titleImage'],
      brief: fieldData['brief'],
      aList: fieldData['mediaDescList'],
      source: fieldData['source'],
    );
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-30 17:54:51

这里不需要StreamBuilder。一旦一个普通的Stream绑定到一个RxType上,你就可以去了。当流数据更改时,它将更新。您只需要更新绑定调用,如下所示。

一个问题是,您应该只是初始化到一个常规的RxList

而不是这个

代码语言:javascript
复制
  Rxn<List<NewsModel>> finalNewsModel = Rxn<List<NewsModel>>();

像这样初始化它。

代码语言:javascript
复制
  RxList<NewsModel> finalNewsModel = <NewsModel>[].obs;

你可能会失去这个吸气剂

代码语言:javascript
复制
  List<NewsModel> get newsModelList => finalNewsModel.value;

因为.value是不需要的,并且不会在正确初始化的RxList上工作。您可以将RxList列表视为常规列表,而不是RxStringRxInt等.这需要.value

您的Obx现在可以在finalNewsModel上构建,并且您可以丢失空检查,因为finalNewsModel被初始化为空列表,并且永远不会为空。

代码语言:javascript
复制
Obx(() {
            if (_controller.finalNewsModel.isEmpty) {
              return Text('Empty List');
            } else {
              return Expanded(
                child: ListView.builder(
                  itemCount: _controller.finalNewsModel.length,
                  itemBuilder: (context, index) {
                    final NewsModel _newsModel =
                        _controller.finalNewsModel[index];
                    return MyContainer(
                      title: _newsModel.title,
                      titleImage: _newsModel.titleImage,
                      index: index,
                    );
                  },
                ),
              );
            }
          }),

至于你想用你的BottomNavBar做什么

在这里,您试图通过更改Document Id来更改流本身的参数。当您绑定到onInit中的流时,它绑定到当时设置的任何Document Id。因此,除非您将其绑定到一个新的流,否则它只会更新该Document中的更改。因此,在您的示例中,只需在finalNewsModel.bindStream(streamDemo());方法中再次调用changeDocId()来更新Stream参数。

代码语言:javascript
复制
  void changeDocId(int index) {
    mainDocId(docIdList[index]);
    finalNewsModel.bindStream(streamDemo()); // only needed because you're updating the Document Id
  }

您也不需要在您的GetBuilder中使用BottomNavBar,除非您需要在BottomNavBar本身上进行视觉上的更改。您所做的就是根据硬编码的RxString值更新List的值。假设您确实需要在BottomNavBar中进行重建,这将是唯一需要调用update()的场景。

我没有完整的Firebase集合结构,但我用一个简化的NewsModel对其进行了测试,并在Firebase控制台中更新了一个String,立即更新Obx小部件。调用changeDocId()将立即返回更新的Document Id的值。

编辑:而且,对于您正在做的事情,mainDocId不需要是一个可观察的字符串。流总是比原始数据类型更昂贵,因此除非您能够对其进行调整,否则最好将它变成如下所示的常规字符串。工作原理完全一样。

代码语言:javascript
复制
 String mainDocId = 'USA';

  // method to change document id based on docId index.
  void changeDocId(int index) {
    mainDocId = docIdList[index];
    finalNewsModel.bindStream(streamDemo());
  }
票数 0
EN

Stack Overflow用户

发布于 2021-05-28 05:48:13

试试这个:

代码语言:javascript
复制
changeDocId(int index) {
   mainDocId.value = docIdList[index];
 }

而不是

代码语言:javascript
复制
changeDocId(int index) {
   mainDocId.value(docIdList[index]);
 }

我相信通过调用方法(rxVar())更新Rx并不会触发小部件的重建,而是使用赋值‘t (rxVar.value=)进行更新。

希望这能解决问题,或者至少能让你更接近修复。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67660041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档