flutter 使用RxList时检测到GetX的使用不当

u7up0aaq  于 2023-02-13  发布在  Flutter
关注(0)|答案(1)|浏览(337)

我创建了一个可观察列表,然后将数据从API存储到列表中,如下所示

class FeedsController extends GetxController {
  final Rx<List<Stories>> _stories = Rx<List<Stories>>([]);

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

  List<Stories> get getStories {
    return _stories.value;
  }

  Future<List<Stories>> getActiveStories() async {
    var url = Uri.parse(storiesURL);
    Map<String, Object> params = {'apikey': apiKey, 'userid': "8"};

    await http.post(url, body: params).then((value) {
      StoriesResponse storiesResponse = storiesResponseFromJson(value.body);
      _stories.value = storiesResponse.stories;
    }).onError((error, stackTrace) {
      debugPrint('Error occurred while fetching stories response: ${error.toString()}');
    });

    return _stories.value;
  }
}

下面是显示Stories List的代码

class _ActiveStoriesListState extends State<ActiveStoriesList> {
  List<Story> _currentUserStories = [];

  final FeedsController _feedsController = Get.find();

  @override
  void initState() {
    Future.delayed(Duration.zero, fetchUserStories);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [ 
        Text('Active Stories',
          style: titleLargeTextStyle.copyWith(fontSize: 22, fontWeight: FontWeight.w600),),
        const SizedBox(height: 10),
        SizedBox(
            height: 100,
            child: Obx(
              () => ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                itemBuilder: (ctx, index) =>
                    ActiveStoriesWidget(story: _currentUserStories[index]),
                itemCount: _currentUserStories.length,
              ),
            )),
      ],
    );
  }

  void fetchUserStories() async {
    List<Stories> stories = _feedsController.getStories;
    stories = stories.where((story) => story.userId == '8').toList();
    _currentUserStories = stories[0].story;
    debugPrint('Active Stories Page: ${_currentUserStories.length}');
  }
}

我尝试过的解决方案是只让ListView可观察(不起作用),让ListView父子可观察也不起作用。我不明白我遗漏了什么。下面是例外

Exception Screenshot
json数据样本

{ "status": 200, "success": [ { "user_id": "4", "first_name": "Abu", "profileImage": "jayspur.com/RallyApp/public/uploads/userImages/…", "story": [ { "story": "jayspur.com/RallyApp/public/uploads/userStories/…", "addeddate": "2023-02-08 09:58:11" } ] } ] }
irlmq6kh

irlmq6kh1#

出现此错误是因为您没有在ListView.builder中使用任何可观察列表。
但在此之前,您应该将您的StatefullWidget转换为StatelessWidget,因为在GetX中,我们不需要任何StatefullWidget
您可以尝试以下代码。
主计长

class FeedsController extends GetxController {
  final Rx<List<Stories>> _stories = Rx<List<Stories>>([]);
  List<Stories> currUserstories = [];

  RxBool isLoading = false.obs;
  @override
  void onInit() {
    super.onInit();
    getActiveStories();
  }

  List<Stories> get getStories {
    return _stories.value;
  }

  Future<List<Stories>> getActiveStories() async {
    isLoading.value = true;
    var url = Uri.parse("storiesURL");
    Map<String, Object> params = {'apikey': apiKey, 'userid': "8"};

    await http.post(url, body: params).then((value) {
      StoriesResponse storiesResponse = storiesResponseFromJson(value.body);
      _stories.value = storiesResponse.stories;
      _stories.value =
          _stories.value.where((story) => story.userId == '8').toList();
      currUserstories = _stories.value[0];
    }).onError((error, stackTrace) {
      debugPrint(
          'Error occurred while fetching stories response: ${error.toString()}');
    });

    isLoading.value = false;
    return _stories.value;
  }
}

查看文件:

class ActiveStoriesList extends StatelessWidget {
  ActiveStoriesList({super.key});

  final FeedsController _feedsController = Get.find();

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          'Active Stories',
          style: titleLargeTextStyle.copyWith(
              fontSize: 22, fontWeight: FontWeight.w600),
        ),
        const SizedBox(height: 10),
        SizedBox(
            height: 100,
            child: Obx(
              () => _feedsController.isLoading.value
                  ? const Center(
                      child: CircularProgressIndicator(),
                    )
                  : ListView.builder(
                      shrinkWrap: true,
                      scrollDirection: Axis.horizontal,
                      itemBuilder: (ctx, index) => ActiveStoriesWidget(
                          story: _feedsController.currUserstories[index]),
                      itemCount: _feedsController.currUserstories.length,
                    ),
            )),
      ],
    );
  }
}

你可能需要稍微调整一下代码,但是核心概念是你应该在控制器内部完成所有的工作,并且只在视图文件中获取数据。
此外,您应该只使用控制器提供的生命周期。例如,onInit而不是initState
如果这不起作用,尝试修改你的控制器文件,这样你就可以在控制器文件本身中得到你想要的列表中的值,并且你可以在视图文件中的控制器中得到你想要的列表。
希望有帮助。

相关问题