标签: bloc

使用 DI 将 BLoC 作为单例注入的效果以及在哪里关闭流?

我正在使用inject.dart将我的块作为单例注入,这是一种不好的做法,即会导致内存泄漏吗?

由于我使用的所有流都是来自 RxDart 的广播流,我想知道单例是否会工作得更好?

如果不是不好的做法,那么关闭流的最佳位置是什么?由于其他小部件可能仍在使用流,因此在有状态小部件(订阅 bloc)的 Dispose() 中执行此操作是否会导致问题?

dependency-injection stream flutter rxdart bloc

6
推荐指数
1
解决办法
2744
查看次数

如何让小部件测试等到 Bloc 更新状态?

我有一个EmailScreen(有状态的小部件),它有一个文本输入和一个按钮。仅当输入有效的电子邮件时该按钮才会启用。

\n\n

我正在使用 Bloc,我的屏幕上有InitialEmailStateValidEmailInputState,并且当我运行该应用程序时它工作正常。

\n\n

在我的小部件测试中,在 bloc 有机会更新状态之前,第二个期望失败了:

\n\n
\n  testWidgets(\'when valid email is input, button is enabled\', (tester) async {\n    const validEmail = \'email@provider.com\';\n\n    emailBloc.listen((event) {\n      print(\'NEW EVENT: \' + event.toString());\n    });\n\n    await bootUpWidget(tester, emailScreen);\n\n    final BottomButton button = tester.widget(\n        find.widgetWithText(BottomButton, \'CONTINUE\'));\n\n    expect(button.enabled, isFalse);\n\n    await tester.enterText(find.byType(TextInputScreen), validEmail);\n    await tester.pumpAndSettle();\n\n    expect(button.enabled, isTrue);\n  });\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我得到的输出:

\n\n
NEW EVENT: InitialEmailState\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following TestFailure object was thrown running a test:\n …
Run Code Online (Sandbox Code Playgroud)

testing flutter bloc

6
推荐指数
1
解决办法
3100
查看次数

一起使用 flutter bloc 库和 websockets 的设计建议

我们有一个 Flutter 应用程序,它使用 websocket 进行服务器发起的通信。我们使用 flutter_bloc 作为整个应用程序的状态管理机制。UI 事件通过 Bloc 状态转换和 BlocBuilder 小部件传送到小部件。

另一个要求是,有些小部件应该根据通过 websocket 从服务器接收到的特定事件来重新渲染。

StreamBuilder 是对 Websocket 上接收到的事件做出反应的自然方式。但不确定将其合并到使用 Blocs 的 UI 小部件中的最佳方法。

当 Bloc 和 websocket 通道一起使用时,希望社区提供有关干净地构造代码的意见。

websocket flutter bloc

6
推荐指数
1
解决办法
4304
查看次数

如何在flutter中使用hydated_bloc保持状态?

我正在尝试使用 Hydrated_bloc 库保持状态,问题是该库的所有示例都非常基本,我想通过使用示例 api 休息来维护状态,但我仍然无法实现此示例的逻辑:

userbloc_bloc.dart

import 'dart:async';
import 'package:di/users/model/user.dart';
import 'package:di/users/repository/cloud_api_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';

part 'userbloc_event.dart';
part 'userbloc_state.dart';

class UserblocBloc extends HydratedBloc<UserblocEvent, UserblocState> {
  @override
  UserblocState get initialState {
     return super.initialState ?? UserblocInitial();

  }

    @override
  UserblocState fromJson(Map<String, dynamic> json) {
    try {
      final usermodel = UserModel.fromJson(json);
      return UserblocLoaded(usermodel);
    } catch (_) {
      return null;
    }
  }

  @override
  Map<String, dynamic> toJson(UserblocState state) {

    if (state is UserblocLoaded) {
      return state.userModel.toJson();
    }else{
      return null;
    }

  }

  @override
  Stream<UserblocState> mapEventToState(
    UserblocEvent …
Run Code Online (Sandbox Code Playgroud)

flutter bloc

6
推荐指数
1
解决办法
2560
查看次数

Flutter Bloc equatable 状态未使用 Map of Strings 属性进行更新

我的 Bloc 状态没有更新,我发现问题可能是Map<String, Map<String, String>未正确比较的属性。如果我错了,请纠正我,但状态会在其他属性更改时更新,而不是在imageUrls属性更新时更新。

这些是我的状态对象

abstract class PropertiesState extends Equatable {
  const PropertiesState();
}

class PropertiesLoaded extends PropertiesState {
  final int count;
  final List<Property> properties;
  final Map<String, Map<String, String>> imageUrls;

  const PropertiesLoaded({
    this.count,
    this.properties,
    this.imageUrls,
  });

  @override
  List<Object> get props => [count, properties, imageUrls];
}
Run Code Online (Sandbox Code Playgroud)

imageUrls 字段可以有任何字符串键/值对。我无法找到有关如何执行此操作的任何信息。

谢谢您的帮助!

dart flutter bloc flutter-bloc

6
推荐指数
2
解决办法
3448
查看次数

具有嵌套数据结构的 Flutter BloC

我有一个嵌套结构,如下所示:

List<Areas>
|-- List<Topics>
|   |-- List<Exercises>
Run Code Online (Sandbox Code Playgroud)

这是我的应用程序的工作流程:

  1. 应用程序已打开
  2. 获取API并显示列表Areas
  3. 用户选择Area并转到下一个屏幕
  4. 获取API并显示主题列表
  5. 用户选择Topic并转到下一个屏幕
  6. 获取API并显示练习列表
  7. 用户需要完成所有这些

我开始使用BloC,但我不确定是否应该对每种类型的数据使用一个 Bloc(因此一个 bloc for Areas,另一个 for Topics,另一个 for Exercises)或仅在一个 Bloc 中处理整个结构。

我看到一个问题,其中State包含整个结构,并且每次从 中获取嵌套列表时都需要更新API。也许这会导致内存问题?

另一方面,每种数据类型都有一个 Bloc 将使它们之间的通信变得复杂。

state management如果更有意义的话,我也愿意改用另一种技术。

任何帮助,将不胜感激。

多谢。

nested hierarchical state-management flutter bloc

6
推荐指数
1
解决办法
339
查看次数

Flutter BLoC `buildWhen` 属性

_CastError 在这段代码的最后一行遇到错误

BlocBuilder buildUsernameField() {
  return BlocBuilder<ProfileBloc, ProfileState>(
    buildWhen: (previous, current) => previous != current && current is EditingUserInfo,
    builder: (context, state) => TextField(
      keyboardType: TextInputType.name,
      controller: TextEditingController(
          text: (state as EditingUserInfo).username.value),
Run Code Online (Sandbox Code Playgroud)

这么说

I/flutter (26787): The following _CastError was thrown building BlocBuilder<ProfileBloc, ProfileState>(dirty, state:
I/flutter (26787): _BlocBuilderBaseState<ProfileBloc, ProfileState>#25b87):
I/flutter (26787): type 'Success' is not a subtype of type 'EditingUserInfo' in type cast
Run Code Online (Sandbox Code Playgroud)

所以发生的事情是,当我处于另一种状态(成功)时,它会尝试构建该小部件。但在buildWhen参数中,我指定小部件仅应在状态为 时构建EditingUserInfo

据我了解,这个错误不应该发生。

这是我的ProfileState

I/flutter (26787): The following _CastError was thrown …
Run Code Online (Sandbox Code Playgroud)

dart flutter bloc

6
推荐指数
1
解决办法
1万
查看次数

Flutter BLoC:Cubits 比 BLoC 更好吗?

我使用 Flutter 工作了很长时间,并发布了很多产品。我从来没有真正喜欢过 BLoC,更喜欢使用 Provider 或后来的 Riverpod。

我只是不明白该事件的概念。为什么我们还需要它?我很困惑,因为它的实际受欢迎程度...... BLoC 有 Cubit 子类,似乎使用起来更简单,但每个人都只是不停地说:“Cubit 更简单,但功能不那么强”。但有什么限制呢?

我什至认为肘尺更有用,同时也更简单:

  1. 使用 Cubit,您只需使用参数调用它的方法。如果需要,您仍然可以监听其状态并获取方法返回值。
  2. 您不需要额外的编码来实现这些事件类型。
  3. 您不需要额外的代码来实现 bloc 如何处理每种事件类型。方法就可以做到这一点。

示例:用户点击某些产品的“添加到购物车”按钮。

肘:

cartCubit.addProduct(productId);
Run Code Online (Sandbox Code Playgroud)

集团:

cartBloc.addEvent(UserAddsProductEvent(productId));
Run Code Online (Sandbox Code Playgroud)

在它们里面:

肘:

void addProduct(String productId) async {
   //some validation...
   if(...){...}
   final result = await cartRepo.addProduct(id);
   if(result == ...) {
      state = someState;
   //....
}
Run Code Online (Sandbox Code Playgroud)

集团:

void addEvent(CartEvent event) {
   if (event is UserAddsProductEvent) {
      _addProduct(event.productId)
      } else if (event is....) {
      //.....
      }
}

void _addProduct(String productId) async {
   //some validation...
   if(...){...}
   final result = …
Run Code Online (Sandbox Code Playgroud)

state-management dart flutter bloc

6
推荐指数
2
解决办法
3433
查看次数

flutter BlocProvider 导航

假设我们使用以下代码导航到“PageA”:

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) {
      return BlocProvider(
        create: (context) => BlocA(),
        child: PageA(),
      );
    },
  ),
);
Run Code Online (Sandbox Code Playgroud)

当“PageA”导航到“PageB”时。我如何访问“BLocA”?我尝试使用以下代码从“PageA”导航到“PageB”,但它崩溃了。

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) {
      return BlocProvider(
        create: (context) => contxt.read<BlocA>(),
        child: PageB(),
      );
    },
  ),
);
Run Code Online (Sandbox Code Playgroud)

navigation flutter bloc

6
推荐指数
1
解决办法
2936
查看次数

由于 mapEventToState 不起作用而引起的 Flutter 块迁移

我正在关注到新块 8.0.0 的迁移。我正在尝试删除 mapEventToState 我在这样做时遇到困难。你能帮我看看该怎么做吗?我已经在下面尝试过,但它不起作用。

旧代码:

class SignInBloc extends Bloc<SignInEvent, SignInState> {
  final AuthenticationRepository authenticationRepository;
  final UserDataRepository userDataRepository;

  SignInBloc(
      {required this.authenticationRepository,
      required this.userDataRepository})
      : super(SignInInitialState());

  SignInState get initialState => SignInInitialState();

  @override
  Stream<SignInState> mapEventToState(
    SignInEvent event,
  ) async* {
    if (event is SignInWithGoogle) {
      yield* mapSignInWithGoogleToState();
    }
  }

Stream<SignInState> mapSignInWithGoogleToState() async* {
    yield SignInWithGoogleInProgressState();
    try {
      String res = await authenticationRepository.signInWithGoogle();
      yield SignInWithGoogleCompletedState(res);
    } catch (e) {
      print(e);
      yield SignInWithGoogleFailedState();
    }
  }
...
Run Code Online (Sandbox Code Playgroud)

迁移代码(不起作用):

class SignInBloc extends Bloc<SignInEvent, …
Run Code Online (Sandbox Code Playgroud)

flutter bloc

6
推荐指数
1
解决办法
6516
查看次数