36

我正在构建一个网络应用程序,它需要一个获取帖子 ID 的路由,然后它将使用该 ID 获取帖子。

我怎么能有 URL 参数让我们说/post/:idid 是参数

我的应用目前看起来像这样:

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
    );
  }
}

编辑:这是我根据@BloodLoss 尝试过的,由于某种原因,我在访问控制台时没有得到任何东西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
    );
  }
}
4

8 回答 8

12

tl;博士

//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"

向下钻取

在一个完美的世界中,您可以访问queryParametersUri.base.queryParameters因为:

Uri.base

返回当前平台的自然基础 URI。在浏览器中运行时,这是当前页面的当前 URL(来自 window.location.href)。当不在浏览器中运行时,这是引用当前工作目录的文件 URI。

但是目前#/在你的路径中存在一个问题,它会混淆Uri.baseUri 的解释。
请关注问题 #33245,直到此问题得到解决,您将能够使用Uri.base.queryParameters

于 2020-06-05T18:08:21.320 回答
4

请点击此链接了解更多信息https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments

在你的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,
          );
        },

或者你可以使用这个插件fluro像 web 一样进行本地化

于 2019-08-19T08:35:24.673 回答
2

我就是这样做的。您可以根据您的要求对其进行编辑。如果您想使用 ?q= 则相应地使用 split by 或 regex

这是传入参数以及作为 /topic/:id 传入 url 的示例

  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());
  }
}
于 2019-12-24T04:13:28.910 回答
2

flutter_modular添加到您的 Flutter Web 项目中。

当前版本:flutter_modular: ^3.1.1

阅读动态路由部分:https ://pub.dev/packages/flutter_modular#dynamic-routes

URL 示例/post?id=123

  1. 使用 MaterialApp 创建您的主小部件并调用 ´´´MaterialApp().modular()´´´ 方法。

     //  app_widget.dart
     import 'package:flutter/material.dart';
     import 'package:flutter_modular/flutter_modular.dart';
    
     class AppWidget extends StatelessWidget {
       @override
       Widget build(BuildContext context) {
         return MaterialApp(
           initialRoute: "/",
         ).modular();
       }
     }
    
  2. 创建您的项目模块文件扩展模块:

     // app_module.dart
     class AppModule extends Module {
       @override
       final List<Bind> binds = [];
    
       @override
       final List<ModularRoute> routes = [
           ChildRoute('/', child: (_, __) => HomePage()),
           ChildRoute('/post', child: (_, args) => PostPage(id: args.queryParams['id'])),
      ];
     }
    

3.在main.dart文件中,将主模块包裹在ModularApp中,用Modular对其进行初始化:

// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';

import 'app/app_module.dart';

void main() => runApp(ModularApp(module: AppModule(), child: AppWidget()));
于 2021-04-27T15:20:14.520 回答
1

这是另一种方法:

我的网址格式: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();
              },
            );
          ;
        },
于 2020-01-15T22:14:26.387 回答
1

我是 Flutter 的新手,我发现了一个古怪的解决方法,...

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

不是很复杂,但有效:-D

于 2020-04-29T08:35:51.037 回答
1

这是一个使用“默认”路由作为我的主要路由的解决方法。

我这样做是因为这似乎是 Flutter 允许我打开其中包含 ID 的 URL 的唯一方法,它不会返回 404。

例如,Flutter 似乎不尊重“?” 分隔器。因此,带有 ID 的 URL 会被 Flutter 读取为未知 URL。例如 site.com/invoice?id=999 将返回 404,即使 /invoice 设置为路由。

我的目标:我有一个 1 页的 Web 应用程序,它一次只显示一张发票,对应于 URL 中的 ID。

我的网址

app.com/#/xLZppqzSiSxaFu4PB7Ui

URL 末尾的数字是 FireStore Doc ID。

这是 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,
                ),
              );
          }
        },

这会将“xLZppqzSiSxaFu4PB7Ui”发送到“发票”小部件。

于 2020-01-15T16:43:58.233 回答
0

使用以下示例尝试 onGenerateRoute

  final info = settings.arguments as Mediainfo?;

    settings = settings.copyWith(
        name: settings.name! + "?info=" + info!.name, arguments: info);
    return MaterialPageRoute(
        builder: (_) => MediaDetails(info: info), settings: settings);
于 2021-11-13T00:27:33.000 回答