Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/

React 变更 - C++ SDK

在此页面上

  • 注册对象变更侦听器
  • 注册集合变更监听器
  • 注册结果collection变更监听器
  • 停止关注变更
  • 变更通知限制

所有 Realm 对象均为活动对象,这表示在修改它们时会自动进行更新。每当发生任何属性变更时,Realm 均会发出通知事件。您可以注册一个通知处理程序来侦听这些通知事件,并使用最新数据更新您的用户界面。

您可以在 Realm 中的特定对象上注册通知处理程序。Realm 会通知您的处理程序:

  • 当删除对象时。

  • 当对象的任何属性发生变更时。

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

处理程序接收一个 object_change对象,其中包含有关更改的信息,例如对象是否已删除。 它可能包括一个PropertyChange对象列表,其中包含有关更改的字段、这些字段的新值(列表属性除外)以及可能的字段的旧值的信息。

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

进行更改时,对 Realm 进行刷新以发出通知。

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

您可以在collection上注册通知处理程序。集合是列表、映射或集属性,可以包含任何受支持的数据类型,包括基元或其他对象。

每当写事务(write transaction)删除、添加或更改collection中的对象时,Realm 都会通知您的处理程序。

通知使用三个索引列表描述自先前通知以来的更改:已删除对象的索引、已插入对象的索引和已修改对象的索引。

重要

顺序很重要

在集合通知处理程序中,始终按以下顺序应用变更:删除、插入和修改。在删除操作之前处理插入操作可能会导致意外行为。

集合通知提供了一个collection_change结构体,用于报告已删除、添加或修改的对象的索引。 如果集合已删除,它还可以通知您。

在此示例中, Person对象将Dog对象列表作为属性:

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

删除犬、添加新犬或修改犬会触发通知处理程序:

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

您可以在结果集合上注册通知处理程序。

每当写事务(write transaction)删除、添加或更改collection中的对象时,Realm 都会通知您的处理程序。

通知使用三个索引列表描述自先前通知以来的变更:已删除对象、已插入对象和已修改对象的索引。

重要

顺序很重要

在集合通知处理程序中,始终按以下顺序应用变更:删除、插入和修改。在删除操作之前处理插入操作可能会导致意外行为。

结果集合通知提供了一个results_change结构体,用于报告已删除、添加或修改的对象的索引。 如果集合已删除,它还可以通知您。

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

observe调用返回的令牌失效时,观察就会停止。 您可以通过调用令牌的unregister()成员函数来显式使其失效。

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

重要

只要您想观察,就保留令牌

调用令牌的析构函数时,通知停止。 例如,如果令牌位于Go作用域的局部变量中。您可以使用std::move将令牌传输到不同作用域中的变量。

嵌套文档中深度超过四级的变更不会触发变更通知。

如果您的数据结构需要侦听第五层深度或更深层的更改,解决方法包括:

  • 重构模式以减少嵌套。

  • 添加“推送以刷新”一类的内容,使用户能够手动刷新数据。

后退

线程