How can a named route have URL parameters in flutter web?

ぐ巨炮叔叔 提交于 2021-02-18 19:57:31

问题


I'm building a web-app which needs to have a route that gets a post ID and then it will fetch the post using the ID.

How can I have URL arguments let's say /post/:id so id is the argument

My app looks like that currently:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // title: "Paste",
      initialRoute: "/",
      theme: ThemeData(
          primarySwatch: Colors.green,
          primaryColor: Colors.blue
      ),
      routes: {
        "/": (context) => HomePage(),
        "/post": (context) => PastieRoute()
      },
      debugShowCheckedModeBanner: false
    );
  }
}

EDIT: This is what I tried according to @BloodLoss and for somereason I don't get anything to the console when accessing localhost:8080/post?id=123

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: "/",
      routes: {
        "/": (context) => HomePage(),
        "/post": (context) => PastieRoute()
      },
      onGenerateRoute: (settings) {
        if (settings.name == "/post") {
          print(settings.arguments); // Doesn't fire :(

          return MaterialPageRoute(
            builder: (context) {
              // TODO
            }
          );
        }
      },
      debugShowCheckedModeBanner: false
    );
  }
}

回答1:


please follow this link further information https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments

on your MaterialApp

  onGenerateRoute: (settings) {
    // If you push the PassArguments route
    if (settings.name == PassArgumentsScreen.routeName) {
      // Cast the arguments to the correct type: ScreenArguments.
      final ScreenArguments args = settings.arguments;

      // Then, extract the required data from the arguments and
      // pass the data to the correct screen.
      return MaterialPageRoute(
        builder: (context) {
          return PassArgumentsScreen(
            title: args.title,
            message: args.message,
          );
        },

or you can nativate like web using this plugin fluro




回答2:


I'm new to Flutter, and I found a quirky workaround,...

import 'dart:html';

String itemID;

//My url looks like this,... http://localhost:57887/#item_screen/12345
//Counted 13 characters for '#item_screen/' then got the substring as below 

 itemID = window.location.hash.substring(13);
 print(itemID) //12345

Not very sophisticated, but worked :-D




回答3:


This is how I did it. You can edit it as per your requirements. If you want to use ?q= then use the split by or regex accordingly

Here is the example of both passing in argument as well as passing in url as /topic/:id

  Route<dynamic> generateRoute(RouteSettings settings) {
  List<String> pathComponents = settings.name.split('/');
  final Map<String, dynamic> arguments = settings.arguments;
  switch ("/"+pathComponents[1]) {
    case shareTopicView:
      return MaterialPageRoute(
          builder: (context) => TopicPageLayout(topicID: pathComponents[2]));
    case internalTopicView:
      return MaterialPageRoute(
          builder: (context) => TopicPageLayout(topicID: arguments['topicID']));
    default:
      return MaterialPageRoute(builder: (context) => LandingPage());
  }
}



回答4:


tl;dr

//in your example: settings.name = "/post?id=123"
final settingsUri = Uri.parse(settings.name);
//settingsUri.queryParameters is a map of all the query keys and values
final postID = settingsUri.queryParameters['id'];
print(postID); //will print "123"

Drilldown

In a perfect world you would access queryParameters with Uri.base.queryParameters because:

Uri.base

Returns the natural base URI for the current platform. When running in a browser this is the current URL of the current page (from window.location.href). When not running in a browser this is the file URI referencing the current working directory.

But currently there is an issue in flutter where you have #/ in your path which messes the Uri.base interpretation of the Uri.
Follow the issue #33245 until this matter is addressed and you will be able to use Uri.base.queryParameters




回答5:


Here's a workaround that uses the 'default' route as my main route.

I did this because it seems to be the only way that Flutter will allow me to open a URL with an ID in it, that doesn't return a 404.

E.g. Flutter does not seem to respect the '?' separator. So a URL with an ID in it, is read by flutter as an unknown URL. E.g. site.com/invoice?id=999 will return a 404, even in /invoice is set up as route.

My goal: I have a 1-page web app that simply displays a single invoice at a time, which corresponds to the ID in the URL.

My URL

app.com/#/xLZppqzSiSxaFu4PB7Ui

The number at the end of the URL is a FireStore Doc ID.

Here's the code in MyApp:

onGenerateRoute: (settings) {
          List<String> pathComponents = settings.name.split('/');
          switch (settings.name) {
            case '/':
              return MaterialPageRoute(
                builder: (context) => Invoice(),
              );
              break;
            default:
              return MaterialPageRoute(
                builder: (context) => Invoice(
                  arguments: pathComponents.last,
                ),
              );
          }
        },

This sends 'xLZppqzSiSxaFu4PB7Ui' to the 'Invoice' widget.




回答6:


And here is another way to do it:

My url pattern: www.app.com/#/xLZppqzSiSxaFu4PB7Ui

onGenerateRoute: (settings) {
          List<String> pathComponents = settings.name.split('/');
          if (pathComponents[1] == 'invoice') {
            return MaterialPageRoute(
              builder: (context) {
                return Invoice(arguments: pathComponents.last);
              },
            );
          } else
            return MaterialPageRoute(
              builder: (context) {
                return LandingPage();
              },
            );
          ;
        },


来源:https://stackoverflow.com/questions/57552885/how-can-a-named-route-have-url-parameters-in-flutter-web

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!