Flutter Riverpod - Инициализация с асинхронными значениями

Я пытаюсь изучить Riverpod, и у меня есть ChangeNotifierProvider, в котором есть несколько полей, которые необходимо инициализировать значением, возвращаемым в результате асинхронной операции. Возможно ли это, поскольку я знаю, что не могу создать ChangeNotifierProvider асинхронно?

Пример ChangeNotifierProvider

class SomeState extends ChangeNotifier {
  String email = '';

  // needs to be set to value returned from
  // shared preferences upon init
}

Если это невозможно, есть ли другой поставщик, который мог бы работать лучше, зная, что я хочу инициализировать его значение возвращенным значением из асинхронного метода?


person swedishcheef    schedule 09.10.2020    source источник
comment
Принуждение состояния к ожиданию возвращенного значения будущего может привести к остановке всего приложения. Вместо этого вызовите метод async при инициализации вашего состояния и, когда он будет завершен, сохраните значение и вызовите notifyListeners(), чтобы перестроить все прослушивающие виджеты.   -  person Abion47    schedule 09.10.2020
comment
Спасибо @ Abion47, в этом есть смысл. Собираюсь попробовать рефакторинг.   -  person swedishcheef    schedule 09.10.2020
comment
Вы можете добавить флаг bool isLoading   -  person Rémi Rousselet    schedule 09.10.2020
comment
Спасибо, @ RémiRousselet, но не уверен, что понимаю, где мне поставить этот флаг?   -  person swedishcheef    schedule 09.10.2020
comment
Внутри вашего SomeState класса   -  person Rémi Rousselet    schedule 09.10.2020
comment
что-то вроде class SomeState extends ChangeNotifier { String email = ''; bool isLoading = false; void init() async { isLoading = true; var res = await method(); email = res.email; isLoading = false; notifylListeners(); } } ??   -  person swedishcheef    schedule 09.10.2020


Ответы (1)


Да, это возможно в качестве комментария Abion47. Позвольте мне показать более подробную информацию в приведенном ниже коде

class EmailNotifier extends ChangeNotifier {
  String email = '';

  void load() {
    functionReturnFuture.then(value) {
      setEmail(value);
    }
  }

  void setEmail(String value) {
    // email loaded but not changed, so no need to notify the listeners
    if(value == email) return;

    // email has loaded and change then we notify listeners
    email = value;
    notifyListeners();
  }
}


var emailNotifier = ChangeNotifierProvider<EmailNotifier>((ref) {
  var notifier = EmailNotifier();

  // load the email asynchronously, once it is loaded then the EmailNotifier will trigger the UI update with notifyListeners
  notifier.load();
  return notifier;
});

Поскольку мы управляем состоянием независимо от пользовательского интерфейса Flutter, ничто не мешает вам запустить код, запускающий изменение состояния, например, в нашем случае notifier.load ().

После установки notifier.load () и адреса электронной почты провайдер инициирует изменение пользовательского интерфейса с помощью notifyListeners ().

Вы можете добиться аналогичного результата, используя FutureProvider.

person channa ly    schedule 21.11.2020