监听另一个 bloc\xe2\x80\x99s 状态更改的最佳实践是什么?
\n这个答案与以前的版本相关,但它在版本 8 中不起作用(.listen方法在集团上不再存在): https: //stackoverflow.com/a/62785980/160919
FilteredTodosBloc({@required this.todosBloc}) {\n todosSubscription = todosBloc.listen((state) {\n if (state is TodosLoadSuccess) {\n add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));\n }\n});}\nRun Code Online (Sandbox Code Playgroud)\n在 flutter_bloc 8 中监听另一个块的状态变化的推荐方法是什么?
\n我分配了MultiBlocProvider一个应用程序,该应用程序有一个底部导航栏,用于导航主页、搜索、愿望清单等主要路线...
我setState(){}用来改变currentPage每条路线。
最近,我通过使用 package 向其中每个添加了Blocflutter_bloc,并且我使用BlocProviderpackage 向每个提供 bloc BlocBuilder,
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
key: _scaffoldKey,
body: PageStorage(
child: Stack(
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 200),
child: BlocProvider<WishlistBloc>(
create: (BuildContext context) => WishlistBloc(WishlistRepository()),
child: currentPage),
),
bottomBar(currentPageScroll)
],
),
bucket: bucket,
),
),
);
}
Run Code Online (Sandbox Code Playgroud)
可以用来MultiBlocProvider提供我需要的所有 BlocsProviders 吗?
他们可能超过 10 个提供商,这会影响应用程序的性能吗?
我正在尝试按照 bloc 模式将参数传递给 bloc 事件,我找到了这篇文章,但是我的 dart 文档找不到dispatch(event) 方法。
我如何将参数传递给这样的东西
main.dart
这有效
_counterBloc.add(Counter.increment);
Run Code Online (Sandbox Code Playgroud)
但这不
_counterBloc.add(Counter.increment(3));
Run Code Online (Sandbox Code Playgroud)
bloc.dart
import 'package:bloc/bloc.dart';
enum CounterEvents { increment }
class CounterBloc extends Bloc<CounterEvents, int> {
@override
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvents event) async* {
switch (event) {
case CounterEvents.increment:
print(event);
yield state + 1;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 flutter_bloc 库并尝试进行单元测试。我正在按照本教程中的说明进行操作,并且效果很好。
但是,如果扩展 Equatable(必需)的 BlocState 具有扩展 Equatable 的许多属性或大型项目列表,以及根据需要定义的 props[] 。
这使得expectLater()匹配正确的发出状态变得困难,因为它试图将确切的实例与其内容匹配,而不仅仅是状态类型或实例。
例如:
考虑以下 State 类:
class BlocState extends Equatable{
final List<String> data;
BlocState({this.data});
@override
List<Object> get props => [data];
}
Run Code Online (Sandbox Code Playgroud)
然后对于这样的发射状态:
List<String> data = ['Mark', 'Mike', 'John']
BlocState({data: data});
Run Code Online (Sandbox Code Playgroud)
这个expectLater会失败
expectLater(
bloc,
emitsInOrder([BlocState(),]), //This will fail as the state does't equals exactly to the real state
)
Run Code Online (Sandbox Code Playgroud)
这一个将会通过:
expectLater(
bloc,
emitsInOrder([BlocState(data: ['Mark', 'Mike', 'John']),]), //This will pass
)
Run Code Online (Sandbox Code Playgroud)
在如此简单的状态下,验证确切的内容是可以的,但如果列表有 100 个项目,如何测试呢?
有没有办法只验证实例类型而不验证内容?
每当我调用toggleLocked 事件时,BlocBuilder 都不会重建小部件。
我在互联网上查了很多资料,发现了这个解释:/sf/answers/4260843121/ 我认为在某个地方我错误地使用了 equatable 包,导致 BlocBuilder 认为没有任何改变(虽然是有)。
我已阅读 Bloc 库中的常见问题解答,并且提供的三个解决方案(可等同/不重用相同状态/使用 fromList 的道具)似乎无法解决问题。
我的肘:
class LockCubit extends Cubit<LockState> {
LockCubit({@required this.repository})
: assert(repository != null),
super(LockInitial());
final LocksRepository repository;
Future<void> fetch() async {
try {
final locks = await repository.fetchLocks();
emit(LocksDisplayed().copyWith(locks));
} on Exception {
emit(LockError());
}
}
Future<void> toggleLocked(int id) async {
try {
final locks = await repository.toggleLocked(id);
emit(LocksDisplayed().copyWith(List.from(locks)));
} on Exception {
emit(LockError());
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的状态:
abstract class LockState extends Equatable {
const LockState(); …Run Code Online (Sandbox Code Playgroud) 我想实现什么目标?
我正在使用Flutter Bloc库作为我的身份验证组件。在登录页面内,我有一些文本字段,例如用户名/密码,我也将与其他页面共享这些文本字段,例如注册页面、忘记密码、更改密码等。基本上,遵循DRY原则。
每个页面(注册、登录、忘记密码等)都有自己的 Bloc 组件。
我的问题 是我找不到将小部件与 Bloc 分离的方法。我希望能够根据使用的页面在有状态小部件中传递任何 BLoc 组件。
为了理解上面写的内容,让我们看一下我的代码。
login.dart登录页面构建方法中的一段代码。
Widget _loginForm(){
return BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
final status = state.formStatus;
if (status is SubmissionFailed) {
...
}
},
child: Form(
key: _formKey,
child: Column(
children: [
// The reusable widget: Email input field.
BlocBuilder<LoginBloc, LoginState>(
builder:(context, state){
return emailInputField(context, state);
}
),
...
Run Code Online (Sandbox Code Playgroud)
现在让我们看一下emailInputField小部件
Widget emailInputField(BuildContext context, dynamic state) {
return TextFormField(
validator: (value) =>
state.isValidEmail …Run Code Online (Sandbox Code Playgroud) 在我的程序中,我有两个不同的 Blocsbloc1和bloc2. 我使用MultiBlocProvider并添加这两个块。现在我想BlocListener在BlocBuilder. MultiBlocProvider因为bloc1我想要BlocBuilderand因为bloc2我想要BlocListener。我怎样才能做到这一点?
Scaffold(
body: MultiBlocProvider(
providers: [
BlocProvider<GenerateFieldsBloc>(
create: (_) => bloc1,
),
BlocProvider<SubmitFieldBloc>(
create: (_) => bloc2,
),
],
child:() //here how can I use both BlocListener and BlocBuilder ???
),
);
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个用于在页面之间进行导航的 Cubit。我的第一次尝试是在我的背景屏幕上实现它,但在尝试执行此操作时出现此错误:
“错误:在此 BlocBuilder<StateStreamable<Object?>, Object?> Widget 上方找不到正确的 Provider<StateStreamable<Object?>>”
我不明白为什么它找不到正确的上下文,因为我的 BlocBuilder 位于小部件树中的 BlocProvider 之上......
这是代码:
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flexmes_mobile_app/buisness_logic/cubit/internet_cubit.dart';
import 'package:flexmes_mobile_app/buisness_logic/utility/app_bloc_observer.dart';
import 'package:flexmes_mobile_app/config/themes.dart';
import 'package:flexmes_mobile_app/ui/screens/auth_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:responsive_sizer/responsive_sizer.dart';
import 'buisness_logic/cubit/navigation_cubit.dart';
import 'config/app_router.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Firebase.initializeApp();
BlocOverrides.runZoned(
() => runApp(MyApp()),
blocObserver: AppBlocObserver(),
);
}
class MyApp extends StatelessWidget {
final AppRouter _appRouter = AppRouter();
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MediaQuery(
data: const MediaQueryData(),
child: ResponsiveSizer(
builder: (context, orientation, deviceType) …Run Code Online (Sandbox Code Playgroud) 我正在尝试解决与 Flutter Bloc 相关的问题。我正在编辑其他人的代码以使其与最新的 flutter_bloc 版本一起使用,但我无法这样做。有人可以重写我的代码以便我可以运行它吗?我看到了很多答案,但我无法理解如何修复我自己的代码。
这是 all_categories_bloc.dart 的完整代码
class AllCategoriesBloc extends Bloc<AllCategoriesEvent, AllCategoriesState> {
AllCategoriesBloc({
this.apiRepository,
}) : super(AllCategoriesInitial()) {
on<GetAllCategories>(_onGetAllCategories);
}
final ApiRepository apiRepository;
Future<void> _onGetAllCategories(
GetAllCategories event,
Emitter<AllCategoriesState> emit,
) async {
try {
emit(const AllCategoriesLoading());
final categoriesModel = await apiRepository.fetchCategoriesList();
emit(AllCategoriesLoaded(categoriesModel));
if (categoriesModel.error != null) {
emit(AllCategoriesError(categoriesModel.error));
}
} catch (e) {
emit(
const AllCategoriesError(
"Failed to fetch all categories data. Is your device online ?",
),
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
all_categories_event.dart 的代码
abstract class AllCategoriesEvent …Run Code Online (Sandbox Code Playgroud) 我目前正在学习使用 BLoC 模式进行 Flutter 和 Dart 的状态管理和架构。
我遇到过两种在小部件中提供对 BLoC 的访问的方法。
1 - 访问小部件并将其传递到另一个屏幕时使用 BLoCProvider 或 BLoCProvider.value。
2 - 将您的 MaterialApp 小部件包装在 BLoCProvider 中,以提供对全局块的访问。
似乎使用第二个选项总是最简单的 - 管理 BLoC 的单个位置,构建上下文引用没有问题,确保单个 BLoC 实例,并允许全局访问!
以这种方式创建和提供所有应用程序 BLoC 是否有任何缺点?是否存在性能问题等?
我正在开发一个复杂的 Web 应用程序,其中我有时需要从后端 API 获取数据。有时,我需要在 Future Builder 中调用 2 个 future 函数来使用它们的值。然而,它使代码变得混乱,因为对于每个 FutureBuilder,我需要检查它是否有数据并返回小部件。看起来像这样。
return FutureBuilder<object>(
future: func1(),
builder:(context, AsyncSnapshot<object> snapshot1){
if(snapshot1.hasData){
return FutureBuilder<object>(
future: func2(),
builder:(context, AsyncSnapshot<object> snapshot2){
if(snapshot2.hasData){
return widget;
}else{
return CircularProgressIndicator();
}
}
),
}else{
return CircularProgressIndicator();
}
}
);
Run Code Online (Sandbox Code Playgroud)
还有其他更简单的方法吗?我只能使用一个 FutureBuilder,这样我就不必每次都返回小部件,即(CircularProgressIndicator)。谢谢。
flutter flutter-layout flutter-web flutter-bloc flutter-futurebuilder
我在 main.dart 中使用 Flutter bloc 来检查用户身份验证。现在我的应用程序中没有主题选择,它是根据设备上的主题以编程方式选择的。我希望我的 AuthBloc 检查并设置用户在应用程序启动时设置的主题。我有一个主题选择页面,用户可以在其中选择一个主题,默认情况下应该是系统主题,您也可以选择浅色和深色。\n我如何在我的 AuthBloc 中实现此功能?\n我的 main.dart
\n return BlocProvider(\n create: (context) => AuthBloc(authRepo: AuthRepo()),\n child: BlocBuilder<AuthBloc, AuthState>(\n builder: (context, state) {\n print(state);\n return MaterialApp(\n navigatorKey: navKey,\n title: 'YiwuMart',\n debugShowCheckedModeBanner: false,\n theme: lightTheme,\n darkTheme: darkTheme,\n home: MainScreen(\n key: scakey,\n ),\n );\n },\n ),\n );\nRun Code Online (Sandbox Code Playgroud)\n我的主题更改屏幕
\nbool isSystemTheme = true;\n bool isLightTheme = false;\n bool isDarkTheme = false;\n\n Row _buildThemeRow(String themeName, bool isSelected) {\n return Row(\n mainAxisAlignment: MainAxisAlignment.start,\n children: [\n SizedBox(width: 5.h),\n Text(themeName, style: TextStyles.bodyStyle),\n …Run Code Online (Sandbox Code Playgroud) flutter ×13
flutter-bloc ×13
bloc ×8
dart ×4
android ×1
builder ×1
cubit ×1
flutter-test ×1
flutter-web ×1
freezed ×1
performance ×1
socket.io ×1