【问题标题】:How to retain data while using ScopedModel in Flutter?在 Flutter 中使用 ScopedModel 时如何保留数据?
【发布时间】:2019-11-16 05:11:31
【问题描述】:

我正在使用 ScopedModel 从 Firebase 数据库中获取一些数据。

我正在获取事件列表。

  1. 我从模型内部的端点获取事件;
  2. 我将事件存储到模型内的List<Event>
  3. 我使用该列表来构建我的ListView
mixin EventModel on Model {
    List<Event> _events = [];

    Future<http.Response> fetchEvents() async {
          http.Response response = await http.get(//Url);

            final List<Event> fetchedEvents = [];

            ... // decode response data into fetchedEvents

            // Add the loaded data to my List
            _events = fetchedEvents;
            notifyListeners();

            ...
      }

}

所以,当我打开EventsPage 时,我要做的第一件事就是获取initState() 中的数据。

class _EventPageState extends State<EventPage> {
  @override
  void initState() {
    super.initState();
      widget.model.fetchEvents();
    }
  }
}

获取网络数据后,我的应用程序中的List 具有网络数据,因此我可以使用它来构建我的ListView

EventsPage.dart

Widget _buildListView(MainModel model) {
    return Center(
      child: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return ItemEventBig(model.events[index], index);
        },
        itemCount: model.events.length,
      ),
    );
  }

我的问题是,如果我导航到另一个页面然后返回到EventsPageinitState() 将被再次调用,所以fetchEvents。让应用重新加载所有事件列表。

我想在我的应用程序运行时保留下载的数据,所以如果用户回到EventsPage,数据不会丢失。

我以前在Android中使用ViewModel来做,在Flutter中怎么做?

我想继续使用 ScopedModel 在 Flutter 中进行状态管理。

可能的解决方案

我认为解决方案是将事件存储在List&lt;Event&gt; 中,就像我正在做的那样。然后,当调用fetchEvents() 时,我可以先检查我的List&lt;Event&gt; 是否不为空,如果是,我不需要再次调用它,因为数据已经加载。

这对我来说似乎是一个糟糕的解决方案,尤其是当我有多个页面获取数据时。假设我加载了第一个,当我转到第二个时,它会假设数据已经加载,因为 List&lt;Event&gt; 不是 null 并且不会再次加载。

【问题讨论】:

    标签: flutter scoped-model


    【解决方案1】:

    查看 Flutter 文档 - https://api.flutter.dev/flutter/widgets/AutomaticKeepAliveClientMixin-mixin.html

    class _EventPageState extends State<EventPage> 
         with AutomaticKeepAliveClientMixin<EventPage> {
      @override
      void initState() {
        super.initState();
          widget.model.fetchEvents();
        }
      }
      @override
      // TODO: implement wantKeepAlive
      bool get wantKeepAlive => true;
    }
    

    【讨论】:

    • 这解决了问题,因为它保留了状态并且在更改选项卡时不会再次调用initState()。需要将super.build(context); 放入build() 方法中,否则会显示警告。
    猜你喜欢
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多