【问题标题】:BlocProvider.of() called with a context that does not contain a Bloc of type CLASS使用不包含 CLASS 类型的 Bloc 的上下文调用 BlocProvider.of()
【发布时间】:2019-09-29 12:49:22
【问题描述】:

在颤振中,我只是了解如何在应用程序上使用Bloc,我想尝试使用此功能实现简单的登录。在实现了一些 bloc 类以在视图上使用它之后

当我尝试将此代码用作时出现错误

BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));

RaisedButton

错误:

使用不包含 Bloc 的上下文调用 BlocProvider.of() LoginListingBloc 类型。

我的看法:

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));
              }),
        ),
      ),
    );
  }
}

LoginListingBloc类:

class LoginListingBloc extends Bloc<LoginListingEvent, LoginListingStates> {
  final LoginRepository loginRepository;

  LoginListingBloc({this.loginRepository});

  @override
  LoginListingStates get initialState => LoginUninitializedState();

  @override
  Stream<LoginListingStates> mapEventToState(
      LoginListingStates currentState, LoginListingEvent event) async* {
    if (event is LoginEvent) {
      yield LoginFetchingState();
      try {
        final loginInfo = await loginRepository.fetchLoginToPage(
            event.loginInfoModel.username, event.loginInfoModel.password);
        yield LoginFetchedState(userInfo: loginInfo);
      } catch (_) {
        yield LoginErrorState();
      }
    }
  }
}

如果你想看主题,还有其他课程

AppApiProvider类:

class AppApiProvider {
  final successCode = 200;

  Future<UserInfo> fetchLoginToPage(String username, String password) async {
    final response = await http.get(Constants.url + "/api/v1/getPersons");
    final responseString = jsonDecode(response.body);
    if (response.statusCode == successCode) {
      print(responseString);
      return UserInfo.fromJson(responseString);
    } else {
      throw Exception('failed to get information');
    }
  }
}

LoginEvent:

class LoginEvent extends LoginListingEvent {
  final LoginInfoModel loginInfoModel;

  LoginEvent({@required this.loginInfoModel}) : assert(loginInfoModel != null);
}

LoginInfoModel:

class LoginInfoModel {
  String username;
  String password;

  LoginInfoModel({this.username, this.password});
}

final testLogin = LoginInfoModel(username:'exmaple',password:'text');

【问题讨论】:

    标签: flutter bloc


    【解决方案1】:

    无需从context 访问 loginListingBloc,因为它存在于当前类中而不是小部件树中。

    改变:

    BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));  
    

    到:

    _loginListingBloc.dispatch(LoginEvent(loginInfoModel: testLogin));
    

    【讨论】:

    • 你能帮我解决这个问题吗? https://stackoverflow.com/q/56207806/1830228 谢谢
    • BLoC 模式的整体思想是将 UI 与业务逻辑分离。如果 BLoC 在小部件内部实例化,则不可能在小部件测试中模拟它。我非常不鼓励这样做。依赖项应该注入到小部件中,而不是相反!
    【解决方案2】:

    对于所有来这里获取错误消息的其他人: 确保始终指定类型并且不要省略它们:

    BlocProvider<YourBloc>(
        create: (context) => YourBloc()
        child: YourWidget()
    );
    

    也为

    BlocProvider.of<YourBloc>(context);
    

    【讨论】:

      猜你喜欢
      • 2021-02-08
      • 2020-10-25
      • 2020-05-20
      • 2020-08-21
      • 2020-12-26
      • 2020-10-16
      • 2020-11-15
      • 2021-06-10
      • 2020-01-25
      相关资源
      最近更新 更多