Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/

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.

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 ...
};

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.

A notificação contém um ChangeSet com propriedades 6 :

  • DeletedIndices é um int[] que contém os índices dos objetos que foram excluídos.

  • InsertedIndices é um int[] que contém os índices dos objetos que foram inseridos.

  • ModifiedIndices é um int[] 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 é um int[] que representa as mesmas entradas que a propriedade ModifiedIndices , mas os índices representam os novos locais na collection depois que todas as alterações foram contabilizadas.

  • IsCleared é um booleano definido para true quando uma collection foi limpa chamando o método Clear() .

  • 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:

  1. exclusões

  2. inserções

  3. modificações

Manipular inserções antes de exclusões pode resultar em comportamento inesperado.

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.
}
});

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);

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();

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.
}
}

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();
}

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;

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.

Voltar

Transações