首页 > 解决方案 > 是否可以将数据存储在某种模型中?

问题描述

我想存储表单中的数据以将其显示在不同的其他视图上。我已经开始获取用户在输入对话框中输入的数据并将它们返回给调用屏幕。但我现在想在不同的其他屏幕上显示这些数据,并且不想一直手动处理数据。

我已经找到了共享首选项或数据库连接的解决方案,但我对在运行时存储数据感兴趣。我想在 MVC 模式中使用模型。

您有使用这种模式的解决方案或示例吗?

标签: fluttermodel-view-controllerruntimestorage

解决方案


提供者 + ChangeNotifier

就像 Sami Haddad 所说,您应该研究状态管理解决方案。我仍然每天都在学习很多关于 Flutter 的知识,但是你有很多 Flutter 的状态管理解决方案。Flutter 文档中的一个是“Provider + ChangeNotifier”解决方案:

https://flutter.dev/docs/development/data-and-backend/state-mgmt/intro

主要思想是,您可以使用 Flutter 中的 ChangeNotifier API 来操作数据,而不是使用该setState()方法在 a 中本地更改状态/数据。StatefulWidget您将创建一个扩展 ChangeNotifier 的自定义类,该类仅负责保持状态(属性)和操作状态(方法)。然后该类需要被实例化并传递到小部件树中。这就是 Provider 包派上用场的地方。您可以提供一个实例化,并且小部件树中的每个小部件都可以访问保存状态的类的数据和方法。这样,您可以从该子树中所有其他小部件中的该自定义类类中操作数据、请求数据等。

我建议对这个概念进行一些尝试。如果您理解它,我建议您也查看这些flutter_bloc软件包。flutter_bloc 有助于组织更多的结构,以一种简单的方式分离你的逻辑、状态管理和小部件。Youtube 上的 Resocoder 有一些非常好的教程:https ://youtu.be/hTExlt1nJZI

Flutter_Bloc

只是一个快速的总结。flutter_bloc 背后的主要思想是你有一个Event. 此事件可以是枚举或类,如:

class FetchAllCategories extends CategoryEvent {
  @override
  List<Object> get props => [];
}

此事件用于触发状态更改。你想要一些事情发生,对吧?这也可能是您要存储的输入字段中的数据。我使用了我的代码中的一个示例。在这种情况下,它想从 API 中获取类别。但首先,需要触发状态变化。这可以由以下代码使用,它向提供者请求 CategoryBloc 实例。(你仍然需要一种方法来实例化并在你的小部件树中提供这个 flutter_bloc 组件。幸运的是,flutter_bloc 包附带了一个BlocProvider!)

@override
Widget build(BuildContext context) {
  final categoryBloc = BlocProvider.of<CategoryBloc>(context);

  FlatButton(
    onPressed: () {
      categoryBloc.add(FetchAllCategories());
    },
  );
}

当按下按钮时,FetchAllCategories()事件开始。包本身的一些样板,但事件进入流并调用以下函数。在此函数中,我们检查事件是否为FetchAllCategories. 如果是这样,

 @override
  Stream<CategoryState> mapEventToState(
    CategoryEvent event,
  ) async* {
    if (event is FetchAllCategories) {
      try {
        // Fetch data from API 
        final List<Category> categories = await categoryRepository.fetchAllCategories();
        // pass the list of categories to the AllCategoriesLoaded class
        yield AllCategoriesLoaded(categories: categories);
      } 
      // catch etc here... 
    }
  }

yield 基本上就像一个返回,但没有“停止”函数。所以一旦事件被调用,这个类就会被你的 UI Widgets 让步。

还记得包含类别的 AllCategoriesLoaded 类吗?这就是您要在 UI 小部件中使用的状态:

class AllCategoriesLoaded extends CategoryState {
  final List<Category> categories;

  AllCategoriesLoaded({@required this.categories}) : assert(categories != null);

  @override
  List<Object> get props => [];
}

现在,只要将 Bloc 提供到其上方的小部件树中,您就可以请求任何小部件中的数据。像这样。记住 AllCategoriesLoaded 类有一个List<Category>

return BlocBuilder<CategoryBloc, CategoryState>(
  builder: (context, state) {
    if (state is AllCategoriesLoaded) {
      return Text(state.categories[0].name);
    }
  },
);

推荐阅读