7

.familyパラメータを再度渡さずに、提供された " " 変更通知子 (既にインスタンス化されており、正しいパラメータを渡している)のインスタンスにアクセスする方法はありますか?

プロバイダ内

ChangeNotifier (パラメーターが必要) のプロバイダーを作成すると、提供されているのと同じ変更通知を取得できますProvider.of<ChangeNotif>(context)

class ChangeNotif extends ChangeNotifier {
  final String id;
  const ChangeNotif(this.id);
}

ChangeNotifierProvider(create: (_) => ChangeNotif("dash"));

Provider.of<ChangeNotif("dash")>(context)適切なパラメーターを使用してプロバイダーが作成されると、 butのような構文を使用せずに、そのウィジェット ツリーの任意の場所にプロバイダーが提供するものを取得できますProvider.of<ChangeNotif>(context)

リバーポッドで

プロバイダーのインスタンスを取得するときにパラメーターをプロバイダーに渡す必要があるため、プロバイダーが提供する変更通知を必要とする子にそれを渡すために、プロバイダーを変数に割り当てる必要がありました。

final changeNotifProvider = ChangeNotifierProvider.family<ChangeNotif, String>((ref, id) => ChangeNotif(id));

class A extends HookWidget {
  build() {
    final _changeNotifProvider = changeNotifProvider("dash");
    final _changeNotif = useProvider(_changeNotifProvider);

    return Column(
     children: [
       B(),
       c(_changeNotifProvider),
     ]
    );
  }
}

_changeNotif子ウィジェットにパラメーターとして渡さずにインスタンス化する方法はありますか? A の子ではない別のウィジェットで _changeNotif の同じインスタンスを取得する方法はありますか (Provider.of<ChangeNotif>(context)新しいパラメーターを渡すことなくプロバイダーで使用するなど)?

4

2 に答える 2

1

この拡張機能を使用してインスタンスのすべてのインスタンスを取得しますStateNotifierProviderFamilyが、ChangeNotifierProviderFamily. それらをプロバイダーに登録する必要があります。

extension StateNotifierProviderFamilyExtension<
    Notifier extends StateNotifier<Value>,
    Value,
    Param> on StateNotifierProviderFamily<Notifier, Value, Param> {
  /// Get all the registered versions of this `StateNotifierProviderFamily`
  ///
  /// This function requires a reader to the current `ProviderScope` to
  /// get the `familyKeysStorageProvider`
  ///
  /// The family needs to be registered with the `familyKeysStorageProvider`,
  /// like this:
  ///
  /// ```dart
  /// final keyStorage = ref.read(familyKeysStorageProvider(myProvider));
  /// keyStorage.state.add(myKey);
  /// ```
  Iterable<T> all<T extends StateNotifierProvider<Notifier, Value>>(
      Reader read) {
    return read(_familyKeysStorageProvider(this))
        .state
        .map((key) => call(key) as T);
  }

  Set<dynamic> keys(Reader read) =>
      read(_familyKeysStorageProvider(this)).state;
  void addKey(Reader read, dynamic key) => this.keys(read).add(key);
}

/// Use this provider to register keys for a `StateNotifierProviderFamily`
/// object.
///
/// After registration of the keys, it is possible to retrieve all registered
/// instances with the `all(Reader read)` method on `StateNotifierProviderFamily`
final _familyKeysStorageProvider =
    StateProvider.family<Set<dynamic>, StateNotifierProviderFamily>((ref, key) {
  return {};
});

次のように登録できます。

final myStateProvider = StateNotifierProvider.family<
    MyStateNotifier,
    MyState,
    MyKey>(
  (ref, key) {
    myStateProvider.addKey(ref.read, key);
    return MyStateNotifier(ref.read, key);
  },
);

もちろん、これを機能させるには拡張機能もインポートする必要があります。

ChangeNotifierProviderFamily私はそれが次のようなものになると思います(私はこれをテストしていません):

extension ChangeNotifierProviderFamilyExtension<Notifier extends ChangeNotifier,
    Param> on ChangeNotifierProviderFamily<Notifier, Param> {
  Iterable<T> all<T extends ChangeNotifierProvider<Notifier>>(Reader read) {
    return read(_notifierFamilyKeysStorageProvider(this))
        .state
        .map((key) => call(key) as T);
  }

  Set<dynamic> keys(Reader read) =>
      read(_notifierFamilyKeysStorageProvider(this)).state;
  void addKey(Reader read, dynamic key) => this.keys(read).add(key);
}

final _notifierFamilyKeysStorageProvider =
    StateProvider.family<Set<dynamic>, ChangeNotifierProviderFamily>(
        (ref, key) {
  return {};
});
于 2021-06-23T07:36:14.763 に答える