Après des heures de recherche sur le sujet et en raison du manque de documentation sur Flutter Web, je pose cette question.
J'essayais de créer une application Web en utilisant flutter et j'avais une exigence où une URL telle que ci-dessous
website.com/user/someUserCode
serait appelée et une page sera lancée où les données (someUserCode
) seront transmises à la page
mais je n'ai pas encore de solutions pour le résoudre.
donc juste arrondir le tout,
Comment passer et récupérer les données à l'aide des méthodes (get/post) pour flutter l'application Web?
MODIFIER 1
Tout ce que je sais/ai encore essayé
J'utilise le code ci-dessous pour lire si certains paramètres sont dans un fichier de classe
final Map<String, String> params = Uri.parse(html.window.location.href).queryParameters;
String data = params["userData"];
tout cela résout en fait la partie Fetch
de ma question (peut-être)
mais la partie où ces données seront transmises à la page via l'URL est toujours manquante.
MODIFIER 2
Comme je n'ai reçu aucune réponse et que je n'ai rien trouvé, j'ai soulevé un ticket sur la page Flutter GitHub ici
toute autre personne recherchant le même problème peut le suivre (s'il est résolu)
Vous pouvez tout obtenir (chemins, paramètres, etc.) de onGenerateRoute
. Votre Home
sera /
et tout ce qui s'y trouve peut être récupéré et utilisé pour rediriger les utilisateurs.
Mon approche pour résoudre ce problème est la suivante. Votre base App()
devrait être comme:
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Website Title',
onGenerateRoute: (settings) => NavigatorRoute.route(settings.name),
);
}
}
et le classeNavigatorRoute
sera:
class NavigatorRoute extends StatefulWidget {
final String path;
static Route<dynamic> route(String path) {
return SimpleRoute(
name: '', // this one is always empty as you didn't route yet
title: 'Website Title',
builder: (_) => NavigatorRoute(path: path),
animated: false
);
}
const NavigatorRoute({Key key, this.path}) : super(key: key);
@override
_NavigatorRouteState createState() => _NavigatorRouteState();
}
class _NavigatorRouteState extends State<NavigatorRoute> {
@override
void initState() {
super.initState();
Future.delayed(Duration(milliseconds: 0), () {
if (widget.path == '/') {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(false), (_) => false);
return;
} else if (widget.path == '/user') {
Navigator.of(context).pushAndRemoveUntil(UserScreen.route(false), (_) => false);
return;
} else if (widget.path.contains('/user/')) {
Navigator.of(context).pushAndRemoveUntil(UserScreen.routeCode(widget.path.split('/')[2]), (_) => false);
return;
} else if (widget.path == '/about') {
Navigator.of(context).pushAndRemoveUntil(AboutScreen.route(), (_) => false);
return;
} else {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(), (_) => false);
return;
}
});
}
@override
Widget build(BuildContext context) {
return SizedBox();
}
}
Le code pour SimpleRoute
est:
class SimpleRoute extends PageRoute {
SimpleRoute({@required String name, @required this.title, @required this.builder, @required this.animated})
: super(settings: RouteSettings(name: name));
final String title;
final WidgetBuilder builder;
final bool animated;
@override
Color get barrierColor => null;
@override
String get barrierLabel => null;
@override
bool get maintainState => true;
@override
Duration get transitionDuration => Duration(milliseconds: 200);
@override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
return animated
? FadeTransition(
opacity: animation,
child: Title(
title: this.title,
color: Theme.of(context).primaryColor,
child: builder(context),
),
)
: Title(
title: this.title,
color: Theme.of(context).primaryColor,
child: builder(context),
);
}
}
Alors, enfin ... si vous souhaitez ouvrir facilement l'un de vos écrans, vous pouvez faire:
class HomeScreen extends StatefulWidget {
static Route<dynamic> route(bool animated) {
return SimpleRoute(name: '/', title: 'Home', builder: (_) => HomeScreen(), animated: animated);
}
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
...
}
Le routeCode
pourrait être:
static Route<dynamic> routeCode(String id) {
return SimpleRoute(name: '/user/$id', title: 'User', builder: (_) => UserScreen(id: id), animated: false);
}
Le principal avantage de faire cela est d'éviter la pile de pages générées en accédant au dernier écran.
Par exemple, si vous utilisez directement onGenerateRoute
pour "www.mywebsite.com/user/userId/edit", Flutter s'ouvrira:
mais avec cette approche, seul "Edit Screen" sera ouvert.
J'ai essayé la méthode ci-dessus de @Mariano Zorrilla mais cela a quand même ouvert les pages dans l'ordre:
/
/user
/user/yFbOfUAwx1OCC93INK8O7VqgBXq2
J'ai trouvé Fluro , et fonctionne efficacement et proprement, il vous suffit d'ajouter un fichier de routage et de faire tout le routage dans un seul fichier plutôt que d'éditer chaque page vers laquelle vous voulez router, voici comment vous l'implémenter :
main.Dart
void main() {
FluroRouter.setupRouter();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Website Title',
onGenerateRoute: FluroRouter.router.generator
);
}
}
fluro_router.Dart
class FluroRouter {
static Router router = Router();
//Define your routers here
static void setupRouter() {
router.define('/', handler: _homeHandler);
router.define('/login', handler: _loginHandler);
router.define('/online-enquiry/:id', handler: _userHandler);
}
//Add your handlers here
static Handler _homeHandler = Handler(handlerFunc: (context, Map<String, dynamic> params) => Home());
static Handler _loginHandler = Handler(handlerFunc: (context, Map<String, dynamic> params) => Login());
static Handler _userHandler = Handler(handlerFunc: (context, Map<String, dynamic> params) => UserProfile(userID: params['userId'].first));
}