【问题标题】:How to pass parameters to flutter web app如何将参数传递给 Flutter Web 应用程序
【发布时间】:2020-04-29 01:53:48
【问题描述】:

在搜索了几个小时后,由于 Flutter Web 上缺乏文档,我问了这个问题。

我正在尝试使用 Flutter 创建一个 Web 应用程序,并且要求 URL 如下所示

website.com/user/someUserCode

将被调用并启动一个页面,其中数据 (someUserCode) 将被传递到页面

但还没有任何解决方案。

所以只是四舍五入,

如何使用(get/post)方法传递和获取数据来flutter web app?

编辑 1

我所知道/尝试过的一切

我正在使用下面的代码来读取某些参数是否正在某个类文件中

final Map<String, String> params = Uri.parse(html.window.location.href).queryParameters;
String data = params["userData"];

这一切实际上解决了我的问题的Fetch 部分(也许)

但是仍然缺少通过 URL 将数据传递到页面的部分。

编辑 2

由于我没有收到任何回复,也找不到任何东西,我在 Flutter GitHub 页面 here 提出了一张票

寻找相同问题的任何其他人都可以在那里跟踪它(如果它得到解决)

【问题讨论】:

  • 试用 Fluro 进行应用路由,以便您管理
  • 我知道这个方法html.window.location.href,但我的问题并没有围绕那里展开,主要问题是如何通过调用将参数传递给该特定页面。

标签: flutter flutter-web


【解决方案1】:

愿你能以一种简单的方式做到这一点:

import 'dart:html';
import 'package:flutter/material.dart';
import 'home_page.dart';

void getParams() {
  var uri = Uri.dataFromString(window.location.href);
  Map<String, String> params = uri.queryParameters;
  var origin = params['origin'];
  var destiny = params['destiny'];
  print(origin);
  print(destiny);
}

void main() {
  getParams();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Your app',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

然后从浏览器调用它:

http://localhost:52695/?origin=pointA&destiny=pointB

输出:

pointA
pointB 

【讨论】:

    【解决方案2】:

    我从@Mariano Zorrilla 尝试了上述方法,但它仍然按顺序打开页面:

    /
    /user
    /user/yFbOfUAwx1OCC93INK8O7VqgBXq2
    

    我找到了Fluro,并且工作效率高且干净,您只需添加一个路由文件并在一个文件中完成所有路由,而不是编辑您要路由到的每个页面,这是您将如何实现它:

    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/:userId', 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));
    }
    

    Source

    【讨论】:

      【解决方案3】:

      您可以从onGenerateRoute 获取所有内容(路径、参数等)。您的 Home 将是 /,并且可以抓取那里的所有内容并用于重定向用户。

      我解决这个问题的方法如下。您的基础 App() 应该是:

      class App extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Website Title',
            onGenerateRoute: (settings) => NavigatorRoute.route(settings.name),
          );
        }
      }
      

      NavigatorRoute将是:

      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.microtask(() {
            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();
        }
      }
      

      SimpleRoute 的代码是:

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

      所以,最后...如果您想轻松打开其中一个屏幕,您可以这样做:

      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> {
      ...
      }
      

      routeCode 可能是:

      static Route<dynamic> routeCode(String id) {
           return SimpleRoute(name: '/user/$id', title: 'User', builder: (_) => UserScreen(id: id), animated: false);
      }
      

      这样做的主要好处是避免访问最后一个屏幕生成的页面堆栈。

      例如,如果您直接使用 onGenerateRoute 表示“www.mywebsite.com/user/userId/edit”,那么 Flutter 将打开:

      • 主屏幕
      • 用户屏幕
      • 用户 ID 屏幕
      • 编辑屏幕

      但使用这种方法,只会打开“编辑屏幕”。

      【讨论】:

      • 如何使用代码推送屏幕?我想不通。
      • 输入必要的 URL 就可以了。如果您的 Flutter Web 域是“mywebsite.com”,那么,如果您想使用“/policy”命名路径访问您的隐私政策,您可以使用“mywebsite.com/#/privacy”,仅此而已。
      猜你喜欢
      • 2022-07-25
      • 2023-03-04
      • 2012-12-24
      • 2017-06-20
      • 2020-02-07
      • 1970-01-01
      • 2021-09-24
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多