Как получить возможность прослушивания от поставщика Riverpod?

#flutter #dart #riverpod

Вопрос:

Я хочу использовать go_router (https://pub.dev/packages/go_router#redirection) вместе с Riverpod .

У меня есть a Provider и a StreamProvider , которые я хотел бы объединить в a Listenable , чтобы их можно было использовать в качестве refreshListenable параметра GoRouter .

Я думаю, мне нужно объединить Provider и а StreamProvider в какое-то Provider (как?).

Каков самый простой способ создать а Listenable из а Provider ?

Редактировать: Я понимаю, что это «отрицает» смысл Riverpod, но приложение уже настроено на Riverpod, и я просто хотел бы добавить go_router.

Ответ №1:

Существует гораздо более простой способ, поскольку ChangeNotifier можно использовать с Riverpod. В репо Riverpod на Github по этому поводу есть проблема с Gihtub. https://github.com/rrousselGit/river_pod/issues/884

Ответил Тим Уиттинг на Gihtub (его код и комментарии ниже):

Вы можете использовать ChangeNotifier с flutter_riverpod.

 final myNotifierProvider = ChangeNotifierProvider<MyNotifier>((ref) => MyNotifier());
class MyNotifier with ChangeNotifier {
  void refresh(){
    notifyListeners();
  }
}
 

Затем вам нужно посмотреть провайдера, у которого вы пытаетесь передать прослушиваемое.

 // 1.0.0-dev riverpod
refreshListenable: ref.watch(myNotifierProvider)
// 0.14.0
refreshListenable: watch(myNotifierProvider) // using a Consumer / ConsumerWidget

 

И использовать в других местах

 // 1.0.0-dev riverpod
ref.read(myNotifierProvider.notifier).refresh();
// 0.14.0
context.read(myNotifierProvider.notifier).refresh();
 

Комментарии:

1. Есть ли способ сделать это с помощью StateNotifier вместо ChangeNotifier ? Я пытался это сделать, но не смог заставить это работать

Ответ №2:

Я решил это следующим образом:

 class AListenable extends ValueNotifier {
  AListenable(value) : super(value);

  void changeValue(newValue) {
    value = newValue;
  }
}

   
 final aListenableInstance = AListenable(false);

 final myProvider = Provider((ref) {

  final my2ndProviderValue = ref.watch(my2ndProvider);

  if (my2ndProviderValue is AsyncError || my2ndProviderValue is AsyncLoading) {
    aListenableInstance.changeValue(false);
    return false;
  }

  aListenableInstance.changeValue(true);
  return true;
});

final _router = GoRouter(
    refreshListenable: aListenableInstance,...);