Как передать параметры в веб-приложение Flutter

После нескольких часов поиска по теме и из-за отсутствия документации на Flutter Web я задаю этот вопрос.

Я пытался создать веб-приложение с использованием flutter и требовал, чтобы URL-адрес, например, ниже

website.com/user/someUserCode

будет вызван, и будет запущена страница, где данные (someUserCode) будут переданы на страницу

но пока нет никаких решений по ее устранению.

так что просто округляя все это,

Как передавать и получать данные с помощью методов (get / post) для работы с веб-приложением?

ИЗМЕНИТЬ 1

Все, что я знаю / пробовал

Я использую приведенный ниже код, чтобы прочитать, относятся ли некоторые параметры к какому-либо файлу класса

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

все это фактически решает Fetch часть моего вопроса (возможно)

но часть, где эти данные будут передаваться на страницу через URL-адрес, все еще отсутствует.

ИЗМЕНИТЬ 2

Поскольку у меня нет ответов и я ничего не могу найти, я поднял заявку на странице Flutter GitHub здесь

любой другой, ищущий ту же проблему, может отследить ее там (если она разрешится)


person Vicky Salunkhe    schedule 11.01.2020    source источник
comment
Попробуйте Fluro для маршрутизации приложений, чтобы вы могли справиться с этим   -  person Andre Cytryn    schedule 12.01.2020
comment
Я знаю этот метод html.window.location.href, но мой вопрос не связан с этим, главный вопрос заключается в том, как передать параметры на эту конкретную страницу, вызвав ее.   -  person Vicky Salunkhe    schedule 12.01.2020


Ответы (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:

  • Домашний экран
  • Экран пользователя
  • Экран UserId
  • Экран редактирования

но при таком подходе будет открыт только экран редактирования.

person Mariano Zorrilla    schedule 11.05.2020
comment
Как вы нажимаете на экран своим кодом? Я не могу понять. - person carlosx2; 02.12.2020
comment
введите нужный URL и все. Если ваш веб-домен flutter - mywebsite.com, то, если вы хотите перейти к своей политике конфиденциальности с маршрутом именования / policy, выполните mywebsite.com/#/privacy и все. - person Mariano Zorrilla; 04.12.2020

Я попробовал описанный выше метод от @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));
}

Источник

person Jackson Lee    schedule 17.05.2020

Можете ли вы сделать это простым способом:

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 
person Cassio Seffrin    schedule 02.04.2021