Поставщик недоступен при переходе на новый экран - PullRequest
0 голосов
/ 08 октября 2019

проблема в том, что я сижу уже пару дней. есть приложение, в котором:

  • в зависимости от состояния AUTH, отображается 'LoginScreen' или 'MainScreen'.

  • в MainScreen Я устанавливаю внизу навигацию с помощьюэкраны (HomeScreen, ShoppingScreen, MyFavor)

  • Я также установил там свои StreamProviders (те, которые зависят от Auth), используя MultiProvider
  • на HomeScreen, когда я User Provider.of (context) это работает так, как должно
  • , но когда я использую:

    `Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) => ProfileScreen(),
      ),
    );
    

`и использую там Provider.of (context), я получаю" Не удалось найти правильного провайдера .... выше этого ... виджет"

Я прочитал некоторые проблемы по этому вопросу, и было решение для провайдеров decler выше MaterailApp, что в моем случае я не могу сделать, потому чтоЯ могу настроить thoese только после успешного завершения Auth.

Попытка передачи контекста (из HomeScreen) в ProfileScreen (через конструктор) и эта работа, но когда значение UserData изменилось, оно не обновило экран (угадывая из-за различий'контексты')

Что я здесь не так делаю, какие-нибудь идеи?: S

Ответы [ 2 ]

1 голос
/ 08 октября 2019

Поставщики "ограничены".

Это означает, что если они размещены внутри экрана, они не доступны за пределами этого экрана.

Это означает, что если поставщик находится в области действия, но к нему необходимо обратиться за пределами маршрута, в котором он был создан, у нас есть два решения:

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

    Если эти два виджета находятся на двух разных маршрутах, то это в основном означает «переместить провайдера выше MaterialApp / * 1012». *.

  • вручную передать провайдер на новый экран (необходимо при использовании Navigator.push)

    Идея заключается в том, чтобы вместо one провайдера, у нас есть два из них, оба используют одно и то же значение, как описано здесь. См. Как охватить ChangeNotifier для некоторых маршрутов, используя Provider? для практического примера.

    Для Navigator.push это может выглядеть так:

    final myModel = Provider.of<MyModel>(context);
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) =>
          ChangeNotifierProvider.value(
            value: myModel,
            child: MyScreen(),
        ),
      ),
    );
    
1 голос
/ 08 октября 2019

Пожалуйста, убедитесь, что корневой виджет вашего приложения - Provider Виджет, он должен быть родителем MaterialWidget. Если это уже так, мне понадобится ваш код для изучения. Как то так

class AppState {
 User loggedInUser;

 bool get isLoggedIn {
  return loggedInUser != null;
 }

 // Other states as per the requirements
 // ...
}
...