React a alterações - .NET SDK
Nesta página
- Registrar um ouvinte de alteração de Realm
- Fique atento às alterações na collection
- Conjuntos de alterações de notificação
- Ser notificado sobre todas as alterações da coleção
- Limitar notificações
- Cancelar o registro de um ouvinte de alterações
- Lidar com o evento CollectionChanged
- Registrar um ouvinte de alteração de objeto
- Cancelar o registro de um ouvinte de alterações
- Alterar limites de notificação
Todos os objetos de Realm são objetos ativos, o que significa que são atualizados automaticamente sempre que são modificados. O Realm emite umevento de notificação sempre que alguma propriedade é alterada.
O sistema de notificação do Realm permite observar e React a alterações em seus dados, independentemente das gravações que causaram as alterações. Para observar as alterações, crie um manipulador de notificações para um Realm, uma collection managed ou um Objeto de Realm que deseja observar. Em seguida, você pode adicionar sua lógica de aplicativo específica relacionada à alteração.
Observação
Para obter informações sobre como vincular alterações de dados à UI em seu projeto, consulte Vinculação de dados.
O Realm emite três tipos de notificações:
Realm de domínio sempre que um domínio específico Realm uma transação de escrita.
Notificações de coleção sempre que alguma alteração de coleção gerenciada, como inserções, atualizações e exclusões de objetos na coleção.
Notificações de objeto sempre que um objeto específico do Realm for alterado.
Observação
As notificações só funcionam quando seu Realm é atualizado regularmente. No thread Principal ou na UI do seu aplicação, as atualizações do Realm acontecem automaticamente. Em threads no background, você mesmo precisa lidar com isso chamando Realm.Refresh() ou instalando um SynchronizationContext na thread antes de abrir o Realm. A biblioteca de terceiros Nito.AsyncEx.Context fornece uma SynchronizationContext
implementação do e uma API conveniente para instalá-la.
Registrar um ouvinte de alteração de Realm
Você pode registrar um manipulador de notificações em um Realm inteiro. O Realm invoca o manipulador de notificações sempre que qualquer transação de escrita nesse Realm é confirmada.
O manipulador não recebe informações específicas sobre a mudança. Isso é útil quando você quer saber que houve uma alteração, mas não precisa saber especificamente qual foi a alteração.
Suponha que você esteja criando um aplicativo de colaboração em tempo real e queira ter um contador que aumente toda vez que uma alteração é feita. Nesse cenário, você pode se inscrever no manipulador de notificações do Realm e adicionar o código que controla o 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 ... };
Fique atento às alterações na collection
Você pode observar alterações em uma coleção de objetos de domínio e propriedades de coleção de domínio em um objeto. Há duas maneiras de ser notificado sobre alterações em uma coleção: registrar um manipulador de notificações na coleção ou lidar com o CollectionChanged evento.
Você pode registrar um manipulador de notificações em uma collection específica dentro de um Realm. A collection pode ser de Objeto de Realm (como realm.All<Person>()
) ou uma propriedade de collection em um Objeto de Realm (como house.Owners
, onde "Proprietários" é do tipo IList
).
O manipulador recebe uma descrição das alterações feitas na collection desde a última notificação. Ao contrário das notificações de todo o Realm, as notificações de collection contêm informações detalhadas sobre a alteração e fornecem as informações necessárias para managed uma lista ou outra exibição que represente a collection na interface do usuário.
O Realm emite uma notificação inicial quando uma assinatura é adicionada. Após a notificação inicial, o Realm fornece notificações de forma assíncrona sempre que uma transação de escrita adiciona, modifica ou remove objetos na collection.
Conjuntos de alterações de notificação
A notificação contém um ChangeSet com propriedades 6 :
DeletedIndices
é umint[]
que contém os índices dos objetos que foram excluídos.InsertedIndices
é umint[]
que contém os índices dos objetos que foram inseridos.ModifiedIndices
é umint[]
que contém os índices antigos dos objetos que foram modificados. Esses índices indicam a posição dos objetos modificados na coleção original antes da ocorrência de quaisquer exclusões ou inserções.NewModifiedIndices
é umint[]
que representa as mesmas entradas que a propriedadeModifiedIndices
, mas os índices representam os novos locais na collection depois que todas as alterações foram contabilizadas.IsCleared
é um booleano definido paratrue
quando uma collection foi limpa chamando o métodoClear()
.Moved
é uma array de estruturas ChangeSet.Move que contêm o índice anterior e o novo índice de um objeto movido dentro da collection.
Importante
Questões importantes
Em manipuladores de notificações de collection, sempre execute as alterações na seguinte ordem:
exclusões
inserções
modificações
Manipular inserções antes de exclusões pode resultar em comportamento inesperado.
Ser notificado sobre todas as alterações da coleção
Para assinar notificações de coleção, chame o método SubscribeForNotifications . SubscribeForNotifications
retorna um token de assinatura que pode ser descartado a qualquer momento para parar de receber notificações sobre a coleção.
O código a seguir mostra como observar uma collection para alterações.
// 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 notificações
O SDK fornece também um KeyPathsCollection, que fornece uma maneira de filtrar os campos que trigger uma notificação. Você passa o KeyPathsCollection
para o método SubscribeForNotifications
. O seguinte código mostra como observar campos específicos:
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);
Cancelar o registro de um ouvinte de alterações
Para cancelar o registro de um ouvinte de alterações, chame Dispose
no token. O seguinte código mostra como fazer isso:
// 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();
Lidar com o evento CollectionChanged
Cada collection do Realm implementa o INotifyCollectionChanged
, que permite usar uma collection diretamente em cenários de vinculação de dados. Como as coleção implementam INotifyCollectionChanged
o , outra abordagem para monitorar as alterações de coleção é lidar com o CollectionChanged evento e verifique o tipo de NotifyCollectionChangedAction.
Importante
Informações menos detalhadas
O manipulador de eventos CollectionChanged
não fornece o mesmo nível de detalhes sobre as alterações que o SubscribeForNotifications
.
O seguinte código mostra como implementar o manipulador de eventos CollectionChanged
:
{ // 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 um ouvinte de alteração de objeto
Você pode registrar um manipulador de notificações em um objeto específico dentro de um Realm para que o SDK o notifique quando qualquer propriedade do objeto for alterada. The handler receives information about which field has changed. Com o nome do campo, você pode obter o novo valor.
O código a seguir mostra como observar um objeto para alterações.
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(); }
Cancelar o registro de um ouvinte de alterações
Quando não quiser mais receber notificações sobre um ouvinte de alterações, cancele o registro do manipulador. O código é o mesmo para uma collection de Objeto de Realm e uma propriedade collection. O código a seguir mostra como cancelar o registro de um ouvinte de alterações em ambos:
// 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;
Alterar limites de notificação
Alterações em documentos aninhados com mais de quatro níveis abaixo não acionam notificações de alterações.
Se você tiver uma estrutura de dados em que precise escutar as alterações em cinco níveis para baixo ou mais profundamente, as soluções alternativas incluem:
Refatore o esquema para reduzir o aninhamento.
Adicione algo como "pressione para atualizar" para permitir que os usuários atualizem os dados manualmente.