Flutter 颤振-数据更改时getx控制器未更新

Flutter 颤振-数据更改时getx控制器未更新,flutter,controller,getx,Flutter,Controller,Getx,我正在开发一个应用程序,它有一个五页的底部导航栏。我使用getx。在第一页中,我列出了数据。我的问题是,当我从数据库中手动更改数据(bottomnavigationbar中的第一页)时,我通过页面,返回到第一页时,我看不到更改 控制器 class ExploreController extends GetxController { var isLoading = true.obs; var articleList = List<ExploreModel>().obs;

我正在开发一个应用程序,它有一个五页的底部导航栏。我使用getx。在第一页中,我列出了数据。我的问题是,当我从数据库中手动更改数据(bottomnavigationbar中的第一页)时,我通过页面,返回到第一页时,我看不到更改

控制器

class ExploreController extends GetxController {
  var isLoading = true.obs;
  var articleList = List<ExploreModel>().obs;

  @override
  void onInit() {
    fetchArticles();
    super.onInit();
  }

  void fetchArticles() async {
    try {
      isLoading(true);
      var articles = await ApiService.fetchArticles();
      if (articles != null) {
        //articleList.clear();
        articleList.assignAll(articles);
      }
    } finally {
      isLoading(false);
    }
    update();
  }
}
classexplorecontroller扩展了GetxController{
var isLoading=true.obs;
var articleList=List().obs;
@凌驾
void onInit(){
fetchArticles();
super.onInit();
}
void fetchArticles()异步{
试一试{
孤岛加载(真);
var articles=await ApiService.fetchArticles();
如果(文章!=null){
//articleList.clear();
条款清单。转让所有(条款);
}
}最后{
孤岛加载(假);
}
更新();
}
}
和我的用户界面

body: SafeArea(
        child: Column(
        children: <Widget>[
          Header(),
          Expanded(
            child: GetX<ExploreController>(builder: (exploreController) {
              if (exploreController.isLoading.value) {
                return Center(
                  child: SpinKitChasingDots(
                      color: Colors.deepPurple[600], size: 40),
                );
              }
              return ListView.separated(
                padding: EdgeInsets.all(12),
                itemCount: exploreController.articleList.length,
                separatorBuilder: (BuildContext context, int index) {
主体:安全区域(
子:列(
儿童:[
Header(),
扩大(
子项:GetX(生成器:(exploreController){
if(exploreController.isLoading.value){
返回中心(
孩子:纺纱机(
颜色:颜色。深紫色[600],尺寸:40),
);
}
返回ListView.separated(
填充:边缘设置。全部(12),
itemCount:exploreController.articleList.length,
separatorBuilder:(BuildContext,int索引){
GetX(生成器:(控制器){
if(controller.isLoading.value){
返回中心(
孩子:纺纱机(
颜色:颜色。深紫色[600],尺寸:40),);
}
返回ListView.separated(
填充:边缘设置。全部(12),
itemCount:controller.articleList.length,
separatorBuilder:(BuildContext,int-index){};
});
GetX(生成器:(控制器){
if(controller.isLoading.value){
返回中心(
孩子:纺纱机(
颜色:颜色。深紫色[600],尺寸:40),);
}
返回ListView.separated(
填充:边缘设置。全部(12),
itemCount:controller.articleList.length,
separatorBuilder:(BuildContext,int-index){};
});

此处不需要GetBuilder,因为它不适用于可观察变量。也不需要在fetchArticles函数中调用update(),因为它仅用于GetBuilder和不可观察变量

因此,您有两个小部件用于更新UI(GetBuilder和Obx),它们都遵循相同的控制器,您所需要的只是Obx。因此Rahuls answer可以工作,或者您可以将Obx留在原位,摆脱GetBuilder,并在构建方法开始时声明和初始化控制器

final exploreController = Get.put(ExploreController());

然后将OBX小部件中初始化的控制器用作扩展的子控件


Obx(() => exploreController.isLoading.value
          ? Center(
              child:
                  SpinKitChasingDots(color: Colors.deepPurple[600], size: 40),
            )
          : ListView.separated(
              padding: EdgeInsets.all(12),
              itemCount: exploreController.articleList.length,
              separatorBuilder: (BuildContext context, int index) {},
            ),
    )

这里不需要GetBuilder,因为它不适用于可观察的变量。也不需要在fetchArticles函数中调用update(),因为它仅用于GetBuilder和不可观察的变量

因此,您有两个小部件用于更新UI(GetBuilder和Obx),它们都遵循相同的控制器,您所需要的只是Obx。因此Rahuls answer可以工作,或者您可以将Obx留在原位,摆脱GetBuilder,并在构建方法开始时声明和初始化控制器

final exploreController = Get.put(ExploreController());

然后将OBX小部件中初始化的控制器用作扩展的子控件


Obx(() => exploreController.isLoading.value
          ? Center(
              child:
                  SpinKitChasingDots(color: Colors.deepPurple[600], size: 40),
            )
          : ListView.separated(
              padding: EdgeInsets.all(12),
              itemCount: exploreController.articleList.length,
              separatorBuilder: (BuildContext context, int index) {},
            ),
    )

如果“手动”更改数据库中的值,则需要一个流来侦听数据库中的更改。 你不能这样做:

var articles = await ApiService.fetchArticles();
您需要这样做:

var articles = await ApiService.listenToArticlesSnapshot();
myList.add(newItem);
myList.refresh();
您解释的方式类似于在导航到另一页并单击按钮后需要刷新数据,然后导航到第一页(GetBuilder)或在第一页(Obx)中自动添加数据。但您的情况很简单,只需检索文章快照,然后在控制器onInit中,使用bindStream方法订阅快照,并最终使用函数ever()对可观察文章列表中的任何更改作出反应。
类似这样的内容:

如果“手动”更改数据库中的值,则需要一个流来侦听数据库中的更改。
var articles = await ApiService.listenToArticlesSnapshot();
myList.add(newItem);
myList.refresh();
你不能这样做:

var articles = await ApiService.fetchArticles();
您需要这样做:

var articles = await ApiService.listenToArticlesSnapshot();
myList.add(newItem);
myList.refresh();
您解释的方式类似于在导航到另一页并单击按钮后需要刷新数据,然后导航到第一页(GetBuilder)或在第一页(Obx)中自动添加数据。但您的情况很简单,只需检索文章快照,然后在控制器onInit中,使用bindStream方法订阅快照,并最终使用函数ever()对可观察文章列表中的任何更改作出反应。
类似这样的内容:

GetX不知道/看不到数据库数据何时更改/更新

var articles = await ApiService.listenToArticlesSnapshot();
myList.add(newItem);
myList.refresh();
您需要告诉GetX在适当的时候重建。

如果将GetX
observable
GetX
Obx
小部件一起使用,则只需为
observable
字段分配一个新值。当
obs
值更改时,将进行重建

如果将GetX与
GetBuilder
一起使用,则需要在
MyController
中调用
update()
方法来重建
GetBuilder
小部件


下面的解决方案使用GetX控制器(即
TabX
)来:

  • 保留应用程序状态:

  • 所有选项卡的列表(
    tabPages
  • 哪个选项卡处于活动状态(
    selectedIndex
  • 公开更改活动/可见选项卡的方法(
    OnItemMapped()

  • 不匹配的() 此方法位于GetXController的
    TabX

    调用时,它将:

  • 设置哪个选项卡