Лучшие практики Flutter обмениваются данными между экранами

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

Решение 1. В конструкторе

В основном, когда мы перемещаемся, мы отправляем данные через следующий виджет конструктора.

Решение 2. В сеансе

Создает синглтон, к которому можно получить доступ из любого места в приложении, и каждый раз, когда вам нужно отправить данные, вы добавляете их в сеанс, и следующий виджет может их получить.

Решение 3. Блоками

Я прочитал это решение, которое выглядит хорошо:

Я создал контейнерный класс BLoC, в котором я создал экземпляры BLoC двух экранов. Затем я установил ссылку из BLoC A на поток BLoC B, куда я хочу отправить данные. BLoC по-прежнему разделены, потому что они ничего не знают друг о друге, BLoC A не проходит через конструктор на BLoC B и наоборот, но он просто знает, что он получит некоторые данные в одном из своих потоков. .

ОБНОВЛЕНО:

Решение 4. Унаследованный виджет

Со статической функцией, например:

static InheritedDataProvider of(BuildContext context) => context.inheritFromWidgetOfExactType(InheritedDataProvider);
}

Таким образом, вы можете получить доступ к данным, инициализированным в родительском элементе, примерно так: final data = InheritedDataProvider.of(context).data;

Может быть, есть и другие решения, и я буду рад их узнать. Спасибо


person Rodrigue    schedule 01.01.2021    source источник
comment
Лично я использую комбинацию solution1 и 3, мне не нравятся синглтоны   -  person Adnan Alshami    schedule 01.01.2021
comment
@AdnanAlshami, почему бы не использовать только раствор 3?   -  person Rodrigue    schedule 01.01.2021
comment
скажем, у меня есть ScreenA, который извлекает список блогов, и ScreenB, чтобы отображать подробности блога. в этом сценарии я передам модель блога с ScreenA на ScreenB вместо того, чтобы загружать ее снова.   -  person Adnan Alshami    schedule 01.01.2021


Ответы (2)


Что использую:

  1. Вызов следующего экрана с Navigator.pushNamed(ctx, '/foo', arguments: bar). Включите arguments только при необходимости (например, для экрана сведений об обновлении).
  2. Централизуйте все возможные маршруты в виджете, содержащем MaterialApp.
  3. Передайте клон переданного аргумента на следующий экран (неизменяемые данные).

В коде:

  ...
  MaterialApp(
    onGenerateRoute: (s) => MaterialPageRoute(builder: (ctx) => _route(s), settings: s),
  )
  ...

  Widget _route(RouteSettings route) {
    switch (route.name) {
      case '/signup':
        return SignupRoute();
      case '/vendor':
        return VendorRoute((route.arguments as Vendor)?.data?.clone());
      default:
        throw ('No match for ${route.name}');
    }
  }
person wiradikusuma    schedule 01.01.2021
comment
почему вы клонируете свой объект? - person Rodrigue; 01.01.2021
comment
@Rodrigue Я использую Mobx.dart, библиотеку управления состоянием, такую ​​как BLoC. Если не клонировать, изменения, внесенные пользователем, будут немедленно отражены в модели - что, если пользователь нажмет «Отмена»? - person wiradikusuma; 02.01.2021

Лучший способ - передать параметр конструктору

Navigator.push(
                context,
                PageTransition(
                    type: PageTransitionType.fade,
                    child: LoginPage(
                      userModel: model,
                    )));

тогда :

class LoginPage extends StatefulWidget {
  LoginPage({this.userModel});
  User userModel;
  @override
  _LoginPageState createState() => _LoginPageState(userModel: userModel);
  }  

 class _LoginPageState extends State with TickerProviderStateMixin {
  User userModel;
  _LoginPageState({this.userModel}); 

   }
}
person hosein moradi    schedule 02.01.2021
comment
Не могли бы вы подробнее рассказать, почему это лучший способ для вас? - person Rodrigue; 03.01.2021