首先,我确实知道 BLoC 应该如何工作,它背后的想法以及我知道构造函数BlocProvider()和BlocProvider.value()构造函数之间的区别。
为简单起见,我的应用程序有 3 个页面,其中包含一个像这样的小部件树:
App()=> LoginPage()=> HomePage()=>UserTokensPage()
我希望我LoginPage()可以访问,UserBloc因为我需要登录用户等。为此,我将LoginPage()构建器包装在App()小部件中,如下所示:
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: BlocProvider<UserBloc>(
create: (context) => UserBloc(UserRepository()),
child: LoginPage(),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
这显然工作得很好。然后,如果用户成功登录,他将被导航到HomePage。现在,我需要访问我的两个不同的块,HomePage所以我用来进一步MultiBlocProvider传递现有的UserBloc并创建一个名为DataBloc. 我这样做:
@override
Widget build(BuildContext context) {
return BlocListener<UserBloc, UserState>(
listener: …Run Code Online (Sandbox Code Playgroud) 我对新版本的 Bloc: 6.0.0 有点困惑,添加 Cubit 概念,是 bloc 贬值了还是我们可以同时使用它们?
我正在使用 flutter bloc 来显示下载进度百分比,但我不断遇到此问题。我认为问题出现在onDone方法中,但我不知道如何解决它。
错误 :
发生异常。_AssertionError ('package:bloc/src/bloc.dart': 断言失败: 第 137 行 pos 7: '!_isCompleted': 在事件处理程序正常完成后调用了emit。这通常是由于事件处理程序中未等待的 future 造成的。请确保使用事件处理程序等待所有异步操作,并在异步操作后调用emit() 之前使用emit.isDone 以确保事件处理程序尚未完成。
坏的
on<Event>((event, emit) {
future.whenComplete(() => emit(...));
});
Run Code Online (Sandbox Code Playgroud)
好的
on<Event>((event, emit) async {
await future.whenComplete(() => emit(...));
});
)
Run Code Online (Sandbox Code Playgroud)
代码 :
import 'package:bloc/bloc.dart';
import 'package:download_progress_with_bloc/downlaod_file.dart';
import 'package:download_progress_with_bloc/download_event.dart';
import 'package:download_progress_with_bloc/download_state.dart';
import 'package:download_progress_with_bloc/permission_handler.dart';
import 'package:download_progress_with_bloc/store_book_repo.dart';
import 'package:http/http.dart' as http;
class DownloadBloc extends Bloc<DownloadEvent, DownloadState> {
DownloadBloc({required this.storeBookRepo}) : super(DownloadInitial()) {
on<DownloadStarted>(onStarted);
on<DownloadProgressed>(onProgressed);
}
final StoreBookRepo storeBookRepo;
http.StreamedResponse? response;
// StreamController? …Run Code Online (Sandbox Code Playgroud) 因此,像大多数人一样,我是Bloc的新手,挥舞着飞镖,将我的头缠住。我已经用Google搜索过,浏览了这里的帖子,但没有找到真正的答案。
所以这是关于用团块和颤动进行导航的。以登录为例。因此,有一个登录页面,后面有一个集团,有时有人按下按钮进行登录。
因此,我们可以在集团中调用一个函数进行验证。我认为这违反严格的方法,但我看到有人这样做。但是,如果登录成功,您如何导航到下一个屏幕?您不应该在一个集团中导航吗?
但是,如果该登录页面正在使用StreamBuilder更改状态,那么您也不能在构建器中添加导航,可以吗?您无法返回导航,而是返回小部件。
您可以在initstate中导航,但是在initstate中可以有一个流构建器来侦听整个组中的状态变化吗?
现在这有点令人困惑,但是我很坚持,因为这应该是前进的方向...
谢谢保罗
我在一个小部件树中有一个 FloatingActionButton ,它有一个BlocProviderfrom flutter_bloc。像这样的东西:
BlocProvider(
builder: (context) {
SomeBloc someBloc = SomeBloc();
someBloc.dispatch(SomeEvent());
return someBloc;
},
child: Scaffold(
body: ...
floatingActionButton: FloatingActionButton(
onPressed: _openFilterSchedule,
child: Icon(Icons.filter_list),
),
)
);
Run Code Online (Sandbox Code Playgroud)
这将打开一个模态底部工作表:
void _openFilterSchedule() {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return TheBottomSheet();
},
);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试SomeBloc使用BlocProvider.of<SomeBloc>(context)inside访问,TheBottomSheet但出现以下错误:
BlocProvider.of() called with a context that does not contain a Bloc of type SomeBloc.
Run Code Online (Sandbox Code Playgroud)
我曾尝试使用/sf/answers/3957352801/ 中描述的解决方案,但仅适用于BottomSheet而不适用于ModalBottomSheet。
注意:这不限于BlocProvider或 …
如下使用类 Bloc 提供程序时,出现错误:
'未为类型'BuildContext'定义方法'ancestorInheritedElementForWidgetOfExactType'。
所以我替换了这条线 context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;
用这条线 context.getElementForInheritedWidgetOfExactType<_BlocProviderInherited<T>>().widget;
但后来我收到以下错误:
Error output from Xcode build:
?
** BUILD FAILED **
Xcode's output:
?
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/dynamic_theme-1.0.1/lib/dynamic_theme.dart:25:20: Error: The method 'ancestorStateOfType' isn't defined for the class 'BuildContext'.
- 'BuildContext' is from 'package:flutter/src/widgets/framework.dart' ('../../../development/flutter/packages/flutter/lib/src/widgets/framework.dart').
Try correcting the name to the name of an existing method, or defining a method named 'ancestorStateOfType'.
return context.ancestorStateOfType(const TypeMatcher<DynamicThemeState>());
^^^^^^^^^^^^^^^^^^^
Command PhaseScriptExecution failed with a nonzero exit code
note: Using new build system
note: Building targets in parallel
note: Planning …Run Code Online (Sandbox Code Playgroud) 使用 BLoC 库时,我们将所有变量存储在状态类中。但是在哪里存储 TextEditingController,它不会改变,但它的值会改变?
假设我有一个像这样的状态类(仅作为示例):
@freezed
abstract class EditItemState with _$EditItemState {
const factory EditItemState.updated({
TextEditingController titleController,
ShoppingItem shoppingItem,
}) = _ShoppingListLoaded;
}
Run Code Online (Sandbox Code Playgroud)
和肘级:
class EditItemCubit extends Cubit<EditItemState> {
EditItemCubit() : super(EditItemState.updated());
Future<void> titleUpdated() async {
emit(
EditItemState.updated().copyWith(
shoppingItem: state.shoppingItem.copyWith(
title: state.titleController.text,
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
所以Cubit类逻辑看起来很混乱。我建议将此类控制器直接保留在小部件或 BLoC/Cubit 类中。这是正确的做法吗?
我想我现在至少有一个模糊的想法,
如何在我的应用程序中使用BLoC,Stream Builder
和继承的小部件(或模型)
(没有什么特别的,但对我来说需要时间),
但玩Scoped模型
我有一个存在的危机:
我觉得他们大多数可以做同样的事情,或者
至少我可以
用它们中的任何一个获得相同的明显效果,
但我没有能力去理解
何时 以及为什么一个比另一个好.
我故意保持开放的问题不要因为我而讨厌我,
但我希望能更好地理解我正在做的事情
以及使用这一个或另一个事件在幕后发生的事情.
谢谢你的耐心等待.弗朗切斯科
Ps:我不能添加'范围模型'标签,如果可以的话,
它可能与像我这样的新手有关
在颤振中,我只是学习了如何Bloc在应用程序上使用,我想尝试使用此功能实现简单的登录。在实现了一些类之后bloc,在视图中使用它
当我尝试使用此代码时出现错误
BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));
Run Code Online (Sandbox Code Playgroud)
里面 RaisedButton
错误:
BlocProvider.of() 使用不包含 LoginListingBloc 类型的 Bloc 的上下文调用。
我的看法 :
class _HomePageState extends State<HomePage> {
LoginListingBloc _loginListingBloc;
@override
void initState() {
super.initState();
_loginListingBloc =
LoginListingBloc(loginRepository: widget.loginRepository);
}
...
@override
Widget build(BuildContext context) {
return BlocProvider(
bloc: _loginListingBloc,
child: Scaffold(
appBar: AppBar(
elevation: 5.0, title: Text('Sample Code', style: appBarTextStyle)),
body: Center(
child: RaisedButton(
child: Text(
'click here',
style: defaultButtonStyle,
),
onPressed: () {
BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));
}),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
LoginListingBloc …
我一直在结合使用本登录教程和 resocoder clean 架构教程来构建登录/身份验证功能。99% 的情况下都可以正常工作,但无法正确响应LoginButton按下的操作。
由于某种原因,当LoginBloc调用时AuthenticationBloc.add(loggedin()), AuthenticationBloc 会AuthenticationAuthenticated()很好地生成状态,但BlocBuilderMain.dart 中的状态不会收到状态更改。即使内部的 SimpleBlocDelegate 在产生OnTransition时也会被触发,但什么也不做。AuthenticationAuthenticatedBlocBuilder
Main.dart看起来像这样:
import 'package:bloc/bloc.dart';
import 'package:flutter_app/dependency_injector.dart' as di;
import 'package:flutter_app/features/login/presentation/pages/login_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'features/login/presentation/bloc/user_login_bloc.dart';
import 'features/login/presentation/bloc/user_login_events.dart';
import 'features/login/presentation/bloc/user_login_states.dart';
class SimpleBlocDelegate extends BlocDelegate {
@override
void onEvent(Bloc bloc, Object event) {
print(event);
super.onEvent(bloc, event);
}
@override
void onTransition(Bloc bloc, Transition transition) {
print(transition);
super.onTransition(bloc, transition);
}
@override
void onError(Bloc bloc, Object error, StackTrace stackTrace) …Run Code Online (Sandbox Code Playgroud) bloc ×10
flutter ×10
navigation ×2
architecture ×1
cubit ×1
dart ×1
flutter-bloc ×1
scoped-model ×1
state ×1