Je bloque sur une étape de mon application et j’aurais besoin de votre aide.
Objectif : J’aimerais avoir une Future<List> lors de mon initState.
Problème : initState ne peut pas retourner un type Future et je ne peux pas utiliser un FutureBuilder() car je veux pouvoir sélectionner toute ou partie de ma liste avec des CheckBox. (avec le setState pour sélectionner ma CheckBox, mon build, et par conséquent, ma liste, se rechargerait à chaque fois que je coche une ligne. C’est pas ce qu’on veut pour l’optimisation ).
J’ai vue que la meilleure solution serait d’utiliser un Provider. Mais j’ai du mal à le mettre en place…
Avez vous peut-être des solutions plus simple qu’un Provider ? Ou pouvez vous m’aider à comprendre les Provider ^^
Hello @AntoLhn,
Pour ma part, je ne gère plus de Future dans mes vues. C’est censé être ton Viewmodel qui récupère la data et ta vue ne fait que récupérer une List récupéré e depuis ton webservice.
Sur ma vue, j’ai une classe abstraite qui me sert d’interface avec mon viewmodel et je définis un getter pour récupérer ma liste.
abstract class IDiscoverViewModel extends ChangeNotifier {
List<Fungus>? get fungusList;
}
class DiscoverView extends StatelessWidget {
final IDiscoverViewModel _viewModel;
const DiscoverView(this._viewModel, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Découvrir les champignons"),
),
body: SafeArea(
child: AnimatedBuilder(
animation: _viewModel,
builder: (context, child) {
final fungusList = _viewModel.fungusList;
Sur mon viewmodel, j’ai encore une interface vers le router et mon getter qui est défini :
abstract class DiscoverRouter {
fungusDetail({required int fungusId});
}
class DiscoverViewModel extends IDiscoverViewModel {
final DiscoverRouter _router;
final List<Fungus> _fungusList;
DiscoverViewModel(this._router, this._fungusList);
@override
List<Fungus> get fungusList => _fungusList;
}
et dans mon router, au lancement de l’app, je déclenche l’appel à mon webservice :
@override
Future<void> setNewRoutePath(NavigationPath configuration) async {
final fungusId = configuration.fungusId;
if (fungusId != null) {
final fungus = await _fungusManager.getFungusDetail(fungusId: fungusId);
if (fungus != null) {
_fungus = fungus;
}
} else {
// Récupération de la liste
_fungusList = await _fungusManager.getFungusDiscover();
}
}
Je ne sais pas si tu as visionné le cours sur le router / navigation 2.0 mais tu auras tous les détails pour gérer cette classe particulière.
C’est beau à voir Tu as parfaitement saisi la logique d’organisation @Tazooou ! Je ne sais pas pour toi, mais depuis que j’organise mon projet comme ça, tout me paraît simple à mettre en place
Ce dernier cours, c’est la fameuse pièce qui te permet de mieux appréhender la vue d’ensemble du puzzle Il me manquait quelque chose entre la théorie des objets des premiers cours et ce que j’implémentais dans mon projet. Maintenant, tout est plus simple et plus clair !
Au niveau de ta vue, tu pourras appeler ta liste avec « screenModel.dealsList »
Le getter c’est juste pour éviter toute modification en dehors du viewmodel.
Pour le router, c’est un peu plus complexe. Ma navigation n’est pas réalisée directement dans un écran mais à l’intérieur d’une classe spécifique qui s’occupe que de la navigation.
Pour aller de mon écran 1 vers le 2, je vais envoyer un évènement vers mon router pour lui dire de créer l’écran 2.
Maxime a fait tout un cours la dessus, je ne pourrais ni même ne saurais te résumer ça en un post
Si tu as accès à la formule, je te recommande fortement de le suivre, on y apprend plein de trucs !!