listenTo<T extends ChangeNotifier> method
- BuildContext? context,
- T? notifier,
- String? name,
- Filter? filter,
- required void listener(),
Locates a single service or inherited model and adds a listener ('subscribes') to it.
The located object must be a ChangeNotifier.
If context
is passed, the ChangeNotifier is located on the widget tree. If the ChangeNotifier is already
located, you can pass it to notifier
. If context
and notifier
are null, a registered ChangeNotifier is
located with type T
and name
, where name
is the optional name assigned to the ChangeNotifier when it was
registered.
filter
is a custom function that receives a list of the names of all the registered objects of type T
and
returns a String? that specifies which name to select. For example, if the registry contained objects of type
BookPage
with names "Page 3", "Page 4", and "Page 5", and you wanted to get the first one found:
final BookPage firstLetter = Bilocator.get<GreekLetter>(filter: (pageNames) => pageNames[0]);
A common use case for passing notifier
is using get to retrieve a registered object and listening to one of
its ValueNotifiers:
// Get (but don't listen to) an object
final cloudService = get<CloudService>();
// listen to one of its ValueNotifiers
final user = listenTo<ValueNotifier<User>>(notifier: cloudService.currentUser).value;
listener
is the listener to be added. A check is made to ensure the listener
is only added once.
StatefulWidget example:
class MyWidget extends StatefulWidget { const MyWidget({Key? key}) : super(key: key); @override State
class _MyWidgetState extends State
Implementation
@protected
T listenTo<T extends ChangeNotifier>({
BuildContext? context,
T? notifier,
String? name,
Filter? filter,
required void Function() listener,
}) {
assert(toOne(context) + toOne(notifier) + toOne(name) <= 1,
'listenTo can only receive non-null for "context", "notifier", or "name" but not two or more can be non-null.');
final notifierInstance = context == null
? notifier ?? Bilocator.get<T>(name: name, filter: filter)
: context.get<T>();
final subscription =
_Subscription(changeNotifier: notifierInstance, listener: listener);
if (!_subscriptions.contains(subscription)) {
subscription.subscribe();
_subscriptions.add(subscription);
}
return notifierInstance;
}