Más Funciones Watch
Ya aprendiste watchValue() para observar propiedades ValueListenable. Ahora exploremos las otras funciones watch.
watchIt - Observar Objeto Completo en get_it
Cuando tu objeto registrado ES un Listenable, usa watchIt():
// Manager that IS a ChangeNotifier
class TodoManagerChangeNotifier extends ChangeNotifier {
List<String> _todos = [];
List<String> get todos => _todos;
void addTodo(String todo) {
_todos.add(todo);
notifyListeners(); // Notify on changes
}
}
// Watch the whole manager
class TodoList extends WatchingWidget {
@override
Widget build(BuildContext context) {
final manager = watchIt<TodoManagerChangeNotifier>();
return ListView.builder(
itemCount: manager.todos.length,
itemBuilder: (context, index) => Text(manager.todos[index]),
);
}
}Cuándo usar watchIt():
- Tu objeto extiende
ChangeNotifieroValueNotifier - Necesitas llamar métodos en el objeto
- El objeto completo notifica cambios
watch - Observar Cualquier Listenable
watch() es el más flexible - observa CUALQUIER Listenable:
class CounterWidget extends WatchingWidget {
const CounterWidget({super.key, required this.counter});
final ValueNotifier<int> counter;
@override
Widget build(BuildContext context) {
// Watch the counter passed as parameter (not from get_it)
final count = watch(counter).value;
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () => counter.value++,
child: Text('Increment'),
),
],
);
}
}Cuándo usar watch():
- Observar objetos
Listenablelocales - Ya tienes una referencia al
Listenable - Caso más genérico
watch() es la Base
watch() es la función más flexible - podrías usarla para reemplazar watchIt() y watchValue():
// Estos son equivalentes:
final manager = watchIt<CounterManager>();
final manager = watch(di<CounterManager>());
// Estos son equivalentes:
final count = watchValue((CounterManager m) => m.count);
final count = watch(di<CounterManager>().count).value;¿Por qué usar las funciones de conveniencia?
watchIt()es más limpio para obtener el objeto completo deget_itwatchValue()proporciona mejor inferencia de tipos y sintaxis más limpia- Cada una está optimizada para su caso de uso específico
Usar watch() Solo para Disparar Reconstrucciones
A veces no necesitas el valor de retorno - solo quieres disparar una reconstrucción cuando un Listenable cambia:
class FormWidget extends WatchingWidget {
const FormWidget({super.key, required this.controller});
final TextEditingController controller;
@override
Widget build(BuildContext context) {
// Watch the controller just to trigger rebuild - don't need the return value
watch(controller);
// Now we can use the controller's current state in our widget tree
return Column(
children: [
TextField(controller: controller),
Text('Character count: ${controller.text.length}'),
ElevatedButton(
onPressed: controller.text.isEmpty ? null : () => print('Submit'),
child: Text('Submit'),
),
],
);
}
}Puntos clave:
watch(controller)dispara reconstrucción cuando el controller notifica- No usamos el valor de retorno - solo llamamos
watch()por el efecto secundario - El widget se reconstruye, así que
controller.text.lengthsiempre está actualizado - El estado de habilitación/deshabilitación del botón se actualiza automáticamente
watchPropertyValue - Actualizaciones Selectivas
Solo se reconstruye cuando una propiedad específica de un objeto padre Listenable cambia:
Firma del método:
R watchPropertyValue<T extends Listenable, R>(
R Function(T) selector,
{String? instanceName, GetIt? getIt}
)class ThemeSwitch extends WatchingWidget {
@override
Widget build(BuildContext context) {
// Only rebuilds when darkMode changes, not language or fontSize
final darkMode = watchPropertyValue((SettingsModel m) => m.darkMode);
return Switch(
value: darkMode,
onChanged: (value) => di<SettingsModel>().setDarkMode(value),
);
}
}La diferencia:
// Rebuilds on EVERY SettingsModel change
final settings = watchIt<SettingsModel>();
final darkMode1 = settings.darkMode;
// Rebuilds ONLY when darkMode changes
final darkMode2 = watchPropertyValue((SettingsModel m) => m.darkMode);Comparación Rápida
// 1. watchValue - Watch ValueListenable property from get_it
final todos = watchValue((TodoManager m) => m.todos);
// 2. watchIt - When manager is a Listenable registered in get_it
final manager = watchIt<CounterModel>();
// 3. watch - Local or direct Listenable
final counter = createOnce(() => ValueNotifier(0));
final count = watch(counter).value;
// 4. watchPropertyValue - Selective updates from Listenable registered in get_it
final darkMode = watchPropertyValue((SettingsModel m) => m.darkMode);Elegir la Función Correcta
Si tienes solo una o dos propiedades que deberían disparar una actualización:
Usa ValueNotifier para cada propiedad y watchValue():
final data = watchValue((DataManager m) => m.data);Si el objeto completo puede ser actualizado o muchas propiedades pueden cambiar:
Usa ChangeNotifier y watchIt():
final manager = watchIt<CounterModel>();O si el rendimiento es importante, usa watchPropertyValue() para actualizaciones selectivas:
// Only rebuild when THIS specific property changes
final darkMode = watchPropertyValue((SettingsModel m) => m.darkMode);Para Listenables locales no registrados en get_it:
Usa watch():
final text = watch(controller).value.text;Ejemplo Práctico
Mezclando diferentes funciones watch:
class Dashboard extends WatchingWidget {
@override
Widget build(BuildContext context) {
// watchValue - for ValueListenable property
final userName = watchValue((SimpleUserManager m) => m.name);
// watchPropertyValue - selective rebuild
final darkMode = watchPropertyValue((SettingsModel m) => m.darkMode);
// watch - local state
final searchQuery = createOnce(() => ValueNotifier<String>(''));
final query = watch(searchQuery).value;
return Scaffold(
appBar: AppBar(
title: Text('Hello, $userName'),
backgroundColor: darkMode ? Colors.black : Colors.blue,
),
body: Column(
children: [
TextField(
onChanged: (value) => searchQuery.value = value,
),
Text('Searching: $query'),
],
),
);
}
}Puntos Clave
✅ watchValue() - Observa propiedades ValueListenable desde get_it (una o dos propiedades) ✅ watchIt() - Observa objetos Listenable completos desde get_it (muchas propiedades cambian) ✅ watchPropertyValue() - Actualizaciones selectivas desde Listenable en get_it (optimización de rendimiento) ✅ watch() - Más flexible, cualquier Listenable (local o parámetro) ✅ Elige basándote en el número de propiedades y patrones de actualización ✅ Mezcla y combina según tus necesidades
Siguiente: Aprende sobre observar múltiples valores.
Ver También
- Your First Watch Functions - Empieza aquí
- Watching Multiple Values - Estrategias para combinar valores
- Watching Streams & Futures - Streams y Futures
- Watch Functions Reference - API completa