- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 tabview,我有流行的、最近的和即将到来的类别。他们在 api 上都有相同的响应。我正在尝试使用 flutter_bloc 从 api 获取数据。以前我使用 rxdart 主题,我为每种类型的数据制作了一个主题。现在使用 flutter 块我想达到同样的目的。我想要做的是在选项卡之间切换。以前我使用 behaviorsubject 将数据保存到下一个事件,但现在我想转换为 bloc 模式。如何使用 flutter_bloc 获得相同类型的结果?或者我需要为每种类型创建块?最后,如何从 api 获取数据,以便在切换选项卡时保持状态?我的 Rxdart 实现:
class DataBloc {
final DataRepo _repository = DataRepo();
final BehaviorSubject<Data> _recent = BehaviorSubject<Data>();
final BehaviorSubject<Data> _popular = BehaviorSubject<Data>();
final BehaviorSubject<Data> _upcoming = BehaviorSubject<Data>();
getData(String type) async {
Data response = await _repository.getData(type);
if (type == "recent") {
_recent.sink.add(response);
} else if (type == "upcoming") {
_upcoming.sink.add(response);
} else {
_popular.sink.add(response);
}
}
dispose() {
_recent?.close();
_popular?.close();
_upcoming?.close();
}
BehaviorSubject<Data> get recent => _recent;
BehaviorSubject<Data> get popular => _popular;
BehaviorSubject<Data> get upcoming => _upcoming;
}
最佳答案
对于您的问题,肯定没有单一的解决方案。我会回答你的问题,我会给你一个完整的实现/示例,以便于理解。
I need to create bloc for each type?
How can I fetch data from api such that when tab is switched, state is persisted?
BlocBuilder
),您都会获得最后一个状态。在我的例子中,我们调用
load()
只有渲染选项卡 View 时才执行一次。
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
///
/// The repository that is shared among all BLOCs
///
final Repository repository = Repository();
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
// For example purpose I will expose them as global cubits
return MultiBlocProvider(
providers: [
BlocProvider<PopularCategoriesCubit>(
create: (context) =>
// Create the cubit and also call the LOAD event right away.
//
// NOTE #4. The cubit is created only when is requested (by
// BlocBuilder, BlocListener, etc). This is why when you move to
// a FRESH NEW tab you see the loading state.
//
PopularCategoriesCubit(repository: repository)..load(),
),
BlocProvider<RecentCategoriesCubit>(
create: (context) =>
RecentCategoriesCubit(repository: repository)..load(),
),
BlocProvider<UpcomingCategoriesCubit>(
create: (context) =>
UpcomingCategoriesCubit(repository: repository)..load(),
),
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
));
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Bloc Tabs"),
bottom: TabBar(
tabs: [
Tab(text: "Popular"),
Tab(text: "Recent"),
Tab(text: "Upcoming"),
],
),
),
body: TabBarView(
children: [
// POPULAR TAB
BlocBuilder<PopularCategoriesCubit, GenericState>(
builder: (context, state) {
if (state.isFailed)
return Text("Failed to fetch popular categories.");
if (state.isLoading)
return Text("Loading popular categories...");
return ListView(
children: [
for (var category in state.categories) Text(category)
],
);
},
),
// RECENT TAB
BlocBuilder<RecentCategoriesCubit, GenericState>(
builder: (context, state) {
if (state.isFailed)
return Text("Failed to fetch recent categories.");
if (state.isLoading)
return Text("Loading recent categories...");
return ListView(
children: [
for (var category in state.categories) Text(category)
],
);
},
),
// UPCOMMING TAB
BlocBuilder<UpcomingCategoriesCubit, GenericState>(
builder: (context, state) {
if (state.isFailed)
return Text("Failed to fetch upcoming categories.");
if (state.isLoading)
return Text("Loading upcoming categories...");
return ListView(
children: [
for (var category in state.categories) Text(category)
],
);
},
),
],
),
// This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
// =============================================================================
///
/// Repository Mock
///
class Repository {
///
/// Retreive data by type.
///
/// NOTE #1. Is better to use enum instead of String.
///
Future<List<String>> getData(String type) async {
// Emulate netword delay
return Future<List<String>>.delayed(Duration(seconds: 2)).then((_) {
switch (type) {
case "popular":
return [
"Popular 1",
"Popular 2",
"Popular 3",
"Popular 5",
"Popular 6"
];
case "recent":
return [
"Recent 1",
"Recent 2",
"Recent 3",
];
case "upcoming":
default:
return [
"Upcomming 1",
"Upcomming 2",
];
}
});
}
}
///
/// This is a generic state used for all categories types
///
/// NOTE #2. Use Equatable. Also if you feel you can break this GenericState in
/// multiple classes as CategoriesLoadedState, CategoriesLoadingState,
/// CategoriesFailedState ...
///
class GenericState {
///
/// Categories data
///
final List<String> categories;
///
/// Tells the data is loading or not
///
final bool isLoading;
///
/// Tells whether the state has errors or not
///
final bool isFailed;
GenericState(
{this.categories, this.isLoading = false, this.isFailed = false});
}
///
/// Popular categories Cubit
///
class PopularCategoriesCubit extends Cubit<GenericState> {
///
/// Repository dependency
///
final Repository repository;
///
/// Cubit constructor. Send a loading state as default.
///
PopularCategoriesCubit({@required this.repository})
: super(GenericState(isLoading: true));
// ==================================
// EVENTS
// ==================================
///
/// Load data from repository
///
void load() async {
//#log
print("[EVENT] Popular Categories :: Load");
// Every time when try to load data from repository put the application
// in a loading state
emit(GenericState(isLoading: true));
try {
// Wait for data from repository
List categories = await this.repository.getData("popular");
// Send a success state
emit(GenericState(categories: categories, isFailed: false));
} catch (e) {
// For debugging
print(e);
// For example purpose we do not have a message
emit(GenericState(isFailed: true));
}
}
}
///
/// Recent categories Cubit
///
class RecentCategoriesCubit extends Cubit<GenericState> {
///
/// Repository dependency
///
final Repository repository;
///
/// Cubit constructor. Send a loading state as default.
///
RecentCategoriesCubit({@required this.repository})
: super(GenericState(isLoading: true));
// ==================================
// EVENTS
// ==================================
///
/// Load data from repository
///
void load() async {
//#log
print("[EVENT] Recent Categories :: Load");
// Every time when try to load data from repository put the application
// in a loading state
emit(GenericState(isLoading: true));
try {
// Wait for data from repository
List categories = await this.repository.getData("recent");
// Send a success state
emit(GenericState(categories: categories, isFailed: false));
} catch (e) {
// For debugging
print(e);
// For example purpose we do not have a message
emit(GenericState(isFailed: true));
}
}
}
///
/// Upcoming categories Cubit
///
class UpcomingCategoriesCubit extends Cubit<GenericState> {
///
/// Repository dependency
///
final Repository repository;
///
/// Cubit constructor. Send a loading state as default.
///
UpcomingCategoriesCubit({@required this.repository})
: super(GenericState(isLoading: true));
// ==================================
// EVENTS
// ==================================
///
/// Load data from repository
///
void load() async {
//#log
print("[EVENT] Upcoming Categories :: Load");
// Every time when try to load data from repository put the application
// in a loading state
emit(GenericState(isLoading: true));
try {
// Wait for data from repository
List categories = await this.repository.getData("upcoming");
// Send a success state
emit(GenericState(categories: categories, isFailed: false));
} catch (e) {
// For debugging
print(e);
// For example purpose we do not have a message
emit(GenericState(isFailed: true));
}
}
}
只需将代码复制并粘贴到 main.dart 中即可查看结果。我尝试尽可能多地注释代码以帮助您理解。
onTap
从 TabBar 如下。
TabBar(
onTap: (tabIndex) {
switch (tabIndex) {
// Popular
case 0:
BlocProvider.of<PopularCategoriesCubit>(context).load();
break;
// Recent
case 1:
BlocProvider.of<RecentCategoriesCubit>(context).load();
break;
// Upcoming
case 2:
BlocProvider.of<UpcomingCategoriesCubit>(context).load();
break;
}
},
tabs: [
Tab(text: "Popular"),
Tab(text: "Recent"),
Tab(text: "Upcoming"),
],
),
注:现在您不必发出
load()
当创建最近的和即将到来的肘时(非默认选项卡) - 因为 Tab tap 会处理这些。
BlocProvider<RecentCategoriesCubit>(
create: (context) =>
RecentCategoriesCubit(repository: repository),
),
BlocProvider<UpcomingCategoriesCubit>(
create: (context) =>
UpcomingCategoriesCubit(repository: repository),
),
关于flutter - 在 tabview 中使用 flutter_bloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64629233/
所以,我正在使用 Django REST 框架创建我的 API 和所有内容。我想检查我是否可以从后端获得响应。所以,我能够得到回应。但是我在调试控制台上看到了一些问题。请帮我找出问题所在。这是我在
我在使用 flutter_bloc 在 Flutter 上实现应用程序时遇到问题.我理解核心概念,但我发现了一个“边缘情况”,其中没有示例或指南(至少我能找到): (我会简化问题)我有一个叫 Auth
我正在用BLoC模式在Flutter中重写一个非常简单的应用程序。但是,当我尝试在应用程序中使用BLoC组件时,出现错误。 我不知道该如何解决,如果有人知道,我将非常高兴! 当我尝试在BlocList
我正在使用 flutter_bloc 库来构建我的应用程序。除了 BlocProvider 之外,我还使用存储库提供程序,因为我将在整个应用程序中广泛使用特定的存储库。但我在上下文方面遇到了问题。以下
我正在尝试 Flutter,我在 github 上提出了许多项目,这些项目声明了存储库并将它们传递给 UI 端的 bloc。 为什么这是正确的做法,而不是在后端(在集团)? 例子: class MyA
BLoC 模式的实现有很多版本。其中之一是 Felix Angelov 的 flutter_bloc。 在其中一个社交媒体上,我看到了 flutter_bloc 的声明 对项目来说不是一个好的选择,应
我正在尝试创建一个 BLOC,它依赖于另外两个基于时间的 bloc 和一个非基于时间的 bloc。我所说的基于时间的意思是,例如,他们正在连接远程服务器,所以这需要时间。它的工作原理是这样的: 登录(
我正在使用flutter_bloc:^6.1.1以及依赖注入(inject)get_it:^5.0.6。当我向集团提交事件时,状态没有改变。 nav_bar_bloc.dart import 'dar
我正在使用 flutter_bloc 包来管理我的应用程序中的状态。我有一个用例,我必须从远程数据库加载初始状态。这要求 initialState 方法是异步的,但它不是。 如果不是通过使用 init
假设我有一个带有嵌套集合的 firestore 数据库。一所学校可以有不同的类(class),每门类(class)有不同的部分,每个部分有不同的页面。真的很简单。 从 Firestore 模式的角度来
我已经使用flutter_bloc创建了一个BLoC,在其中我可以收听流。当父窗口小部件(以及BLoC对象)被释放时,我想关闭流。 class ChatBloc extends Bloc { //
我有一个 tabview,我有流行的、最近的和即将到来的类别。他们在 api 上都有相同的响应。我正在尝试使用 flutter_bloc 从 api 获取数据。以前我使用 rxdart 主题,我为每种
假设我想在每次调用 Api 时检查互联网连接,如果没有互联网,调用会抛出异常,例如 NoInternetException,然后向用户显示一个状态屏幕,告诉他检查他们的连接。 如果不为 flutter
我是 Flutter 的新手,目前正在研究 DI。 我正在使用 flutter_bloc 和 provider 包。 flutter_bloc 附带一个 RepositoryProvider,我现在问
我是 Flutter 的新手,目前正在研究 DI。 我正在使用 flutter_bloc 和 provider 包。 flutter_bloc 附带一个 RepositoryProvider,我现在问
我最近在 youtube ( https://pub.dev/packages/flutter_bloc ) 上观看了 felix Angelov 的 flutter_bloc 包 (https://
我在 flutter 中遇到了附加的小部件测试问题。当我单独运行测试时,每个测试都成功了;但是,当我运行整个 main() 方法时,前三个测试成功,但后两个测试失败,并出现以下异常: Expected
为什么当我们需要使用带有 flutter_bloc 的 Equatable 类时? ,还有我们需要的 Prop 呢?这是在 flutter 中以块模式创建状态的示例代码,请我需要详细的答案。先感谢您
我正在Flutter中开始使用Bloc。任何人都可以告诉我什么是真正的“flutter_bloc”和“bloc”软件包。 是相同的。 何时/如何使用它。 谢谢 最佳答案 “bloc”包包含您将在Blo
我有一个 flutter 应用程序,在其中我在 listView 小部件中显示员工列表及其姓名和销售额。我为每个员工提供了两个按钮来增加或减少他们的销售额。 我正在使用flutter_bloc用于状态
我是一名优秀的程序员,十分优秀!