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

React a alterações - C++ SDK

Nesta página

  • Registrar um ouvinte de alteração de objeto
  • Registrar um ouvinte de alteração de coleção
  • Registrar um ouvinte de alteração da collection de resultados
  • Parar de observar as 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 um evento de notificação sempre que alguma propriedade é alterada. Você pode registrar um manipulador de notificações para ouvir esses eventos de notificação e atualizar sua interface do usuário com os dados mais recentes.

Você pode registrar um manipulador de notificações em um objeto específico dentro de um domínio. O realm notifica seu manipulador:

  • Quando o objeto é excluído.

  • Quando qualquer uma das propriedades do objeto é alterada.

auto token = object.observe([&](auto&& change) { ... }

O manipulador recebe um objeto object_change que contém informações sobre as alterações, como se o objeto foi excluído. Ela pode incluir uma lista de objetos PropertyChange que contêm informações sobre quais campos foram alterados, os novos valores desses campos (exceto nas propriedades de lista) e, possivelmente, os valores antigos dos campos.

if (change.error) {
rethrow_exception(change.error);
}
if (change.is_deleted) {
std::cout << "The object was deleted.\n";
} else {
for (auto& propertyChange : change.property_changes) {
std::cout << "The object's " << propertyChange.name
<< " property has changed.\n";
auto newPropertyValue =
std::get<std::string>(*propertyChange.new_value);
std::cout << "The new value is " << newPropertyValue << "\n";
}
}

Ao fazer alterações, refresh() o domínio para emitir uma notificação.

auto config = realm::db_config();
auto realm = realm::db(std::move(config));
// Create an object and move it into the database.
auto dog = realm::Dog{.name = "Max"};
realm.write([&] { realm.add(std::move(dog)); });
auto dogs = realm.objects<realm::Dog>();
auto specificDog = dogs[0];
// Set up the listener & observe object notifications.
auto token = specificDog.observe([&](auto&& change) {
try {
if (change.error) {
rethrow_exception(change.error);
}
if (change.is_deleted) {
std::cout << "The object was deleted.\n";
} else {
for (auto& propertyChange : change.property_changes) {
std::cout << "The object's " << propertyChange.name
<< " property has changed.\n";
auto newPropertyValue =
std::get<std::string>(*propertyChange.new_value);
std::cout << "The new value is " << newPropertyValue << "\n";
}
}
} catch (std::exception const& e) {
std::cerr << "Error: " << e.what() << "\n";
}
});
// Update the dog's name to see the effect.
realm.write([&] { specificDog.name = "Wolfie"; });
// Deleting the object triggers a delete notification.
realm.write([&] { realm.remove(specificDog); });
// Refresh the database after the change to trigger the notification.
realm.refresh();
// Unregister the token when done observing.
token.unregister();

Você pode registrar um manipulador de notificações em uma collection. Uma collection é uma propriedade de lista, mapa ou conjunto que pode conter qualquer tipo de dados suportado, incluindo primitivos ou outros objeto.

O Realm notifica seu manipulador sempre que uma transação de escrita remove, adiciona ou altera objeto na collection.

As notificações descrevem as alterações desde a notificação anterior com três listas de índices: os índices dos objetos que foram removidos, inseridos e modificados.

Importante

Questões importantes

Em manipuladores de notificações de collection, sempre execute alterações na seguinte ordem: exclusões, inserções e modificações. Manipular inserções antes de exclusões pode resultar em comportamento inesperado.

As notificações de coleção fornecem uma estrutura collection_change que relata o índice dos objetos que são removidos, adicionados ou modificados. Ele também pode notificá-lo se a coleção foi excluída.

Neste exemplo, o objeto Person tem uma lista de objetos Dog como uma propriedade:

struct Person {
std::string name;
std::vector<Dog*> dogs;
};
REALM_SCHEMA(Person, name, dogs)

Remover um cão, adicionar um novo cão ou modificar um cão Atlas Triggers o manipulador de notificações:

// Set up the listener & observe a collection.
auto token = person.dogs.observe([&](auto&& changes) {
if (changes.collection_root_was_deleted) {
std::cout << "The collection was deleted.\n";
} else {
// Handle deletions, then insertions, then modifications.
for (auto& collectionChange : changes.deletions) {
std::cout << "The object at index " << std::to_string(collectionChange)
<< " was removed\n";
}
for (auto& collectionChange : changes.insertions) {
std::cout << "The object at index " << std::to_string(collectionChange)
<< " was inserted\n";
}
for (auto& collectionChange : changes.modifications) {
std::cout << "The object at index " << std::to_string(collectionChange)
<< " was modified\n";
}
}
});
// Remove an object from the collection, and then add an object to see
// deletions and insertions.
realm.write([&] {
person.dogs.clear();
person.dogs.push_back(&dog2);
});
// Modify an object to see a modification.
realm.write([&] { dog2.age = 2; });
// Refresh the realm after the change to trigger the notification.
realm.refresh();
// Unregister the token when done observing.
token.unregister();

Você pode registrar um manipulador de notificações em uma coleção de resultados.

O Realm notifica seu manipulador sempre que uma transação de escrita remove, adiciona ou altera objeto na collection.

As notificações descrevem as alterações desde a notificação anterior com três listas de índices: os índices dos objetos que foram excluídos, inseridos e modificados.

Importante

Questões importantes

Em manipuladores de notificações de collection, sempre execute alterações na seguinte ordem: exclusões, inserções e modificações. Manipular inserções antes de exclusões pode resultar em comportamento inesperado.

As notificações da coleção de resultados fornecem uma estrutura results_change que relata o índice dos objetos que são excluídos, adicionados ou modificados. Ele também pode notificá-lo se a coleção foi excluída.

// Get a results collection to observe
auto dogs = realm.objects<realm::Dog>();
// Set up the listener & observe results notifications.
auto token = dogs.observe([&](auto&& changes) {
try {
if (changes.collection_root_was_deleted) {
std::cout << "The collection was deleted.\n";
} else {
// Handle deletions, then insertions, then modifications.
for (auto& resultsChange : changes.deletions) {
std::cout << "The object at index " << std::to_string(resultsChange)
<< " was deleted\n";
}
for (auto& resultsChange : changes.insertions) {
std::cout << "The object at index " << std::to_string(resultsChange)
<< " was inserted\n";
}
for (auto& resultsChange : changes.modifications) {
std::cout << "The object at index " << std::to_string(resultsChange)
<< " was modified\n";
}
}
} catch (std::exception const& e) {
std::cerr << "Error: " << e.what() << "\n";
}
});
// Delete and then add an object to see deletions and insertions.
realm.write([&] {
realm.remove(firstDog);
realm.add(std::move(dog2));
});
// Modify an object to see a modification.
realm.write([&] { dog2.age = 2; });
// Refresh the database after the change to trigger the notification.
realm.refresh();
// Unregister the token when done observing.
token.unregister();

A observação para quando o token retornado por uma chamada do observe se torna inválido. Você pode invalidar explicitamente um token ligando para sua função de nó unregister() .

// Unregister the token when done observing.
token.unregister();

Importante

Retenha os tokens pelo tempo que desejar observar

As notificações param quando o destruidor do token é chamado. Por exemplo, se o token estiver em uma variável local fora de escopo. Você pode utilizar o std::move para transferir o token para uma variável em um escopo diferente.

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

Segmentação