en flutter, j'apprends juste comment utiliser Bloc
sur les applications et je veux essayer d'implémenter une connexion simple avec cette fonctionnalité. après avoir implémenté une classe de bloc
pour l'utiliser sur la vue
j'obtiens une erreur lorsque j'essaie d'utiliser ce code comme
BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));
à l'intérieur RaisedButton
Erreur:
BlocProvider.of () appelé avec un contexte qui ne contient pas de bloc de type LoginListingBloc.
Mon avis :
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
classe:
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();
}
}
}
}
et d'autres classes si vous voulez voir le thème
AppApiProvider
classe:
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');
Pas besoin d'accéder à loginListingBloc depuis context
car il existe dans la classe courante et non dans l'arborescence des widgets.
changement:
BlocProvider.of<LoginListingBloc>(context).dispatch(LoginEvent(loginInfoModel: testLogin));
à:
_loginListingBloc.dispatch(LoginEvent(loginInfoModel: testLogin));
Pour tous les autres qui viennent ici pour le message d'erreur: assurez-vous de toujours spécifier les types et ne les omettez pas:
BlocProvider<YourBloc>(
create: (context) => YourBloc()
child: YourWidget()
);
et aussi pour
BlocProvider.of<YourBloc>(context);