Todos los objetos de Realm son objetos vivos, lo que significa que se actualizan automáticamente cada vez que se modifican. Realm emite un evento de notificación siempre que cambie alguna propiedad.
Realm's notification system allows you to watch for and react to changes in your data, independent of the writes that caused the changes. To observe changes, you create a notification handler for a Realm, a managed collection, or a Realm object that you want to watch. You can then add your specific app logic related to the change.
Nota
For information on binding data changes to the UI in your project, see Data Binding.
Realm emits three kinds of notifications:
Notificaciones de reino cada vez que un reino específico realiza una transacción de escritura.
Notificaciones de colección cada vez que se cambia una colección gestionada, como inserciones, actualizaciones y eliminaciones de objetos en la colección.
Notificaciones de objetos siempre que un objeto Realm específico cambie.
Nota
Las notificaciones solo funcionan cuando tu dominio se actualiza regularmente. En el hilo principal o de interfaz de usuario de tu aplicación, las actualizaciones del dominio se realizan automáticamente. En los hilos en segundo plano, debes gestionar esto tú mismo llamando a Realm.Refresh() o instalando un SynchronizationContext.en el hilo antes de abrir el dominio. La biblioteca de terceros Nito.AsyncEx.Context proporciona una SynchronizationContext Implementación y una API conveniente para instalarlo.
Register a Realm Change Listener
Puedes registrar un manejador de notificaciones en todo un realm. Realm invoca al manejador de notificaciones cada vez que cualquier transacción de escritura en ese realm se confirma.
The handler receives no specific information about the change. This is useful when you want to know that there has been a change but do not need to know specifically what change has occurred.
Supone que estás creando una aplicación colaborativa en tiempo real y deseas tener un contador que aumente cada vez que se realice un cambio. En este escenario, podrías suscribirte al gestor de notificaciones del realm y añadir el código que controla el indicador.
// Observe realm notifications. realm.RealmChanged += (sender, eventArgs) => { // The "sender" object is the realm that has changed. // "eventArgs" is reserved for future use. // ... update UI ... };
Vigile los cambios de colección
You can watch for changes on a collection of realm objects and realm collection properties on an object. There are two ways to be notified about changes to a collection: register a notification handler on the collection or handle the CollectionChanged event.
You can register a notification handler on a specific collection within a realm. The collection can be of realm objects (like realm.All<Person>()) or a collection property on a realm object (like house.Owners, where "Owners" is of type IList).
El handler recibe una descripción de los cambios realizados en la colección desde la última notificación. A diferencia de las notificaciones de todo el realm, las notificaciones de colección contienen información detallada sobre el cambio y ofrecen la información que necesitas para gestionar una lista u otra vista que represente la colección en la Interfaz de Usuario.
Realm emite una notificación inicial cuando se añade una suscripción. Después de la notificación inicial, Realm envía notificaciones de forma asíncrona cada vez que una transacción de escritura agrega, modifica o remueve objetos en la colección.
Notification ChangeSets
The notification contains a ChangeSet with 6 properties:
DeletedIndicesis anint[]that contains the indices of the objects that were deleted.InsertedIndicesis anint[]that contains the indices of the objects that were inserted.ModifiedIndicesis anint[]that contains the old indices of the objects that were modified. These indices indicate the position of the modified objects in the original collection before any deletions or insertions ocurred.NewModifiedIndicesis anint[]that represents the same entries as theModifiedIndicesproperty, but the indices represent the new locations in the collection after all changes have been accounted for.IsClearedis a boolean set totruewhen a collection has been cleared by calling theClear()method.Movedes una matriz de estructuras ChangeSet.Move que contienen el índice anterior y nuevo de un objeto movido dentro de la colección.
Importante
El orden importa
En los controladores de notificaciones de las colecciones, siempre aplica los cambios en el siguiente orden:
eliminaciones
inserciones
modificaciones
Manejar inserciones antes de eliminaciones puede resultar en un comportamiento inesperado.
Recibe notificaciones de todos los cambios de colección
Para suscribirse a las notificaciones de recopilación, llame al método SubscribeForNotifications. SubscribeForNotifications devuelve un token de suscripción que se puede eliminar en cualquier momento para dejar de recibir notificaciones sobre la recopilación.
El siguiente código muestra cómo observar una colección en busca de cambios.
// Watch for collection notifications. var subscriptionToken = realm.All<Dog>() .SubscribeForNotifications((sender, changes) => { if (changes == null) { // This is the case when the notification is called // for the first time. // Populate tableview/listview with all the items // from `collection` return; } // Handle individual changes foreach (var i in changes.DeletedIndices) { // ... handle deletions ... } foreach (var i in changes.InsertedIndices) { // ... handle insertions ... } foreach (var i in changes.NewModifiedIndices) { // ... handle modifications ... } if (changes.IsCleared) { // A special case if the collection has been cleared: // i.e., all items have been deleted by calling // the Clear() method. } });
Limitar notificaciones
The SDK provides also provides a KeyPathsCollection, which provides a way to filter the fields that will trigger a notification. You pass the KeyPathsCollection to the SubscribeForNotifications method. The following code shows how to observe specific fields:
var query = realm.All<Person>(); KeyPathsCollection kpc; // Use one of these equivalent declarations to // specify the fields you want to monitor for changes: kpc = KeyPathsCollection.Of("Email", "Name"); kpc = new List<KeyPath> {"Email", "Name"}; // To get all notifications for top-level properties // and 4 nested levels of properties, use the `Full` // static value: kpc = KeyPathsCollection.Full; // To receive notifications for changes to the // collection only and none of the properties, // use the `Shallow` static value: kpc = KeyPathsCollection.Shallow; query.SubscribeForNotifications(notificationCallback, kpc);
Unregister a Change Listener
To unregister a change listener, call Dispose on the token. The following code shows how to do this:
// Watch for collection notifications. // Call Dispose() when you are done observing the // collection. var token = realm.All<Dog>() .SubscribeForNotifications((sender, changes) => { // etc. }); // When you no longer want to receive notifications: token.Dispose();
Handle the CollectionChanged Event
Cada colección INotifyCollectionChanged de Realm implementa, lo que permite usar una colección directamente en escenarios de enlace de datos. Dado que INotifyCollectionChanged las colecciones implementan, otra forma de supervisar los cambios en las colecciones es gestionar el evento CollectionChanged y comprobar el tipo de NotifyCollectionChangedAction.
Importante
Información menos detallada
El controlador de eventos CollectionChanged no proporciona el mismo nivel de detalle sobre los cambios que SubscribeForNotifications.
The following code shows you how to implement the CollectionChanged event handler:
{ // Subscribe to a query realm.All<Dog>().AsRealmCollection().CollectionChanged += HandleCollectionChanged; // Subscribe to a property collection gracie.Owners.AsRealmCollection().CollectionChanged += HandleCollectionChanged; ... } private void HandleCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { // Use e.Action to get the // NotifyCollectionChangedAction type. if (e.Action == NotifyCollectionChangedAction.Add) { // etc. } }
Registrar un objeto de escucha de cambios
Puedes registrar un gestor de notificaciones en un objeto específico dentro de un realm para que el SDK te avise cuando cambie alguna de las propiedades del objeto. El gestor recibe información sobre qué campo ha cambiado. Con el nombre del campo, puedes obtener el nuevo valor.
El siguiente código muestra cómo observar un objeto para detectar cambios.
var artist = realm.All<Person>() .FirstOrDefault(p => p.Name == "Elvis Presley"); artist.PropertyChanged += (sender, eventArgs) => { var changedProperty = eventArgs.PropertyName!; Debug.WriteLine( $@"New value set for 'artist': '{changedProperty}' is now {artist.GetType() .GetProperty(changedProperty).GetValue(artist)}"); }; realm.Write(() => { artist.Name = "Elvis Costello"; }); realm.Refresh(); }
Unregister a Change Listener
When you no longer want to receive notifications on a change listener, you unregister the handler. The code is the same for both a collection of realm objects and a collection property. The following code shows how to unregister a change listener on both:
// Unsubscribe from notifications on a // realm listener realm.RealmChanged -= OnRealmChanged; // Unsubscribe from notifications on a // collection of realm objects realm.All<Item>().AsRealmCollection() .CollectionChanged -= OnItemsChangedHandler; // Unsubscribe from notifications on a // collection property items.AsRealmCollection().CollectionChanged -= OnItemsChangedHandler;
Change Notification Limits
Changes in nested documents deeper than four levels down do not trigger change notifications.
If you have a data structure where you need to listen for changes five levels down or deeper, workarounds include:
Refactorice el esquema para reducir la anidación.
Add something like "push-to-refresh" to enable users to manually refresh data.