J'utilise la bibliothèque flutter_bloc pour architecturer mon application. En plus du BlocProvider, j'utilise le Repository Provider, car je vais utiliser un dépôt spécifique de manière extensive dans mon application. Mais j'ai un problème en ce qui concerne le contexte. Voici un extrait de mon code :
main.dart
void main() async {
.......
appRepository _appRepository = AppRepository();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(
BlocProvider(
builder: (context) =>
AuthenticationBloc(appRepository: _appRepository)..dispatch(AppStarted()),
child: App(appRepository: _appRepository,),
),
);
});
}
class App extends StatelessWidget {
............
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (BuildContext context, AuthenticationState state) {
.....
if (state is AuthenticationUnauthenticated) {
return SafeArea(
top: false,
bottom: false,
child: RepositoryProvider(
builder: (context) => _appRepository,
child: LoginPage(firebaseMessaging: _firebaseMessaging),
),
);
}
......
},
),
);
}
}
Le bouton d'enregistrement se trouve dans le formulaire de connexion :
register_button.dart
class RegisterButton extends StatelessWidget {
final FirebaseMessaging _firebaseMessaging;
RegisterButton({
Key key,
@required FirebaseMessaging firebaseMessaging,
}) : assert(firebaseMessaging != null),
_firebaseMessaging = firebaseMessaging,
super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Don't have an account?", style: TextStyle(color: Colors.black)),
SizedBox(width: 4.0),
GestureDetector(
child: Text("Register here!",
style: TextStyle(
color: Color(0xFF585B8D), fontWeight: FontWeight.w500)),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
return RegisterPage(
firebaseMessaging: _firebaseMessaging,
);
}),
);
},
)
],
);
}
register_page.dart
class RegisterPage extends StatelessWidget {
final FirebaseMessaging _firebaseMessaging;
RegisterPage({
Key key,
@required FirebaseMessaging firebaseMessaging,
}) : assert(firebaseMessaging != null),
_firebaseMessaging = firebaseMessaging,
super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
builder: (context) => RegisterBloc(
appRepository: RepositoryProvider.of<AppRepository>(context),
firebaseMessaging: _firebaseMessaging,
),
child: RegisterForm(),
),
);
}
}
Question :
J'obtiens une erreur lorsque je clique sur le bouton d'enregistrement de mon formulaire de connexion qui se présente comme suit :
No ancestor could be found starting from the context that was passed to RepositoryProvider.of<AppRepository>().
This can happen if:
1. The context you used comes from a widget above the RepositoryProvider.
2. You used MultiRepositoryProvider and didn't explicity provide the RepositoryProvider types.
Good: RepositoryProvider<AppRepository>(builder: (context) => AppRepository())
Bad: RepositoryProvider(builder: (context) => AppRepository()).
The context used was: BlocProvider<RegisterBloc>(dirty, state: _DelegateWidgetState#a87b2(lifecycle state: created))
Pourquoi est-ce que je reçois cette erreur ? Ce problème semble être résolu si je place le fournisseur de référentiel en tant qu'enfant du blocprovider et app en tant que fournisseur de référentiel enfant dans la fonction principale, puis en supprimant les différents fournisseurs de référentiel dans App(). Je suppose que le problème vient du fait que l'on pousse la route de la page matérielle à partir du bouton. Je ne pense pas comprendre comment le contexte ou le fournisseur fonctionne exactement dans Flutter. Je pensais que le provider recherchait l'arbre des widgets pour le dépôt/bloc, est-ce que le fait de pousser une route rompt d'une certaine manière cette continuité ?