Reactに対応する - .NET SDK
項目一覧
すべての Realm オブジェクトはライブ オブジェクトであるため、変更されるたびに自動的に更新されます。 Realm では、プロパティが変更されるたびに通知イベントが発行されます。
Realmの通知システムを使用すると、変更の原因となった書込み (write) とはReactに、データ内の変更を監視し、対応することができます。 変更を監視するには、監視対象の Realm、管理対象コレクション、または Realm オブジェクトの通知ハンドラーを作成します。 その後、変更に関連する特定のアプリ ロジックを追加できます。
注意
プロジェクト内の UI へのデータ変更のバインディングについて詳しくは、「データのバインディング 」を参照してください。
Realm は 3 種類の通知を発行します。
注意
通知は、 邦土が定期的に更新される場合にのみ機能します。アプリケーションのメイン スレッドまたはUIスレッドでは、 邦土 の更新は自動的に行われます。バックグラウンド スレッドでは、 Realm.Refresh() を呼び出すか、SyncronizationContext{ をインストールして、これを自分で処理する必要があります 邦土を開く前に、 スレッドで 。サードパーティのライブラリ nito.AsyncEx.Context は、SynchronizationContext
の実装と、それをインストールするための便利なAPIを提供します。
Realm 変更リスナーの登録
通知ハンドラーは Realm 全体で登録できます。 Realm は、その Realm で書込みトランザクションがコミットされるたびに通知ハンドラを呼び出します。
ハンドラーは、変更に関する具体的な情報を受け取りません。 これは、変更があったことを確認したいが、どのような変更が発生したかを具体的に把握する必要がない場合に便利です。
リアルタイムの連携アプリを作成していて、変更が行われるたびに増加するカウンターを用意したいとします。 このシナリオでは、Realm 通知ハンドラーをサブスクライブし、インジケーターを制御するコードを追加できます。
// Observe realm notifications. realm.RealmChanged += (sender, eventArgs) => { // The "sender" object is the realm that has changed. // "eventArgs" is reserved for future use. // ... update UI ... };
コレクションの変更の監視
Realm オブジェクトのコレクションとオブジェクト上の Realmコレクションプロパティの変更を監視できます。 コレクションの変更を通知するには、コレクションに通知ハンドラーを登録する方法と、 Collectionchanged を処理する方法の 2 つがあります。 イベント。
Realm 内の特定のコレクションに通知ハンドラーを登録できます。 コレクションは、Realm オブジェクト( realm.All<Person>()
など)または Realm オブジェクト上のコレクション プロパティ( house.Owners
など)にすることができます。「Owner」はタイプIList
です)。
ハンドラーは、最後の通知以降にコレクションに加えられた変更の説明を受け取ります。 レルム全体の通知とは異なり、コレクション通知には変更に関する詳細情報が含まれ、UI でコレクションを表すリストやその他のビューを管理するために必要な情報が提供されます。
Realm は、サブスクリプションが追加されると初期通知を発行します。 最初の通知後、書込みトランザクションによってコレクション内のオブジェクトが追加、変更、または削除されるたびに、Realm は非同期に通知を送信します。
通知変更セット
通知には、 6プロパティを持つChangeSetが含まれています。
DeletedIndices
は、削除されたオブジェクトのインデックスを含むint[]
です。InsertedIndices
は、挿入されたオブジェクトのインデックスを含むint[]
です。ModifiedIndices
は、変更されたオブジェクトの古いインデックスを含むint[]
です。 これらのインデックスは、削除または挿入が発生する前に、元の コレクション内の変更されたオブジェクトの位置を示します。NewModifiedIndices
は、ModifiedIndices
プロパティと同じエントリを表すint[]
ですが、インデックスはすべての変更を考慮した後のコレクション内の新しい場所を表します。IsCleared
は、Clear()
メソッドを呼び出してコレクションがクリアされた場合にtrue
に設定されたブール値です。Moved
は、コレクション内で移動されたオブジェクトの以前のインデックスと新しいインデックスを含むChangeSet.Move構造体の配列です。
重要
順序は重要
コレクション通知ハンドラーでは、常に次の順序で変更を適用します。
deletes
inserts
transformations
削除前に挿入を処理すると、予期しない動作が発生する可能性があります。
すべてのコレクションの変更が通知される
コレクション通知をサブスクライブするには、 SubscribeForNotificationsメソッドを呼び出します。 SubscribeForNotifications
は、コレクションの通知の受信を停止するためにいつでも破棄できるサブスクライブ トークンを返します。
次のコードは、コレクションの変更を監視する方法を示しています。
// 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. } });
通知を制限する
SDK はKeyPathsCollectionも提供します。これは、通知をtriggerするフィールドをフィルタリングする方法を提供します。 KeyPathsCollection
をSubscribeForNotifications
メソッドに渡します。 次のコードは、特定のフィールドを観察する方法を示しています。
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);
変更リスナーの登録解除
変更リスナーの登録を解除するには、トークンでDispose
を呼び出します。 次のコードは、これを行う方法を示しています。
// 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();
Collection変更イベントの処理
すべての Realm コレクションはINotifyCollectionChanged
を実装しています。これにより、データ バインディング シナリオでコレクションを直接使用できます。 コレクションはINotifyCollectionChanged
を実装しているため、コレクションの変更をモニタリングする別の方法は、 CollectionChecked を処理することです。 イベントをチェックし、 NotifyCollectionchangedAction のタイプを確認します。
重要
詳細情報は少ない
CollectionChanged
イベント ハンドラーは、 SubscribeForNotifications
と同じレベルの変更に関する詳細を提供しません。
次のコードは、 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. } }
オブジェクト変更リスナーの登録
Realm 内の特定のオブジェクトに通知ハンドラーを登録すると、オブジェクトのプロパティが変更されたときに SDK が通知するようになります。 ハンドラーは、どのフィールドが変更されたに関する情報を受け取ります。 フィールド名を使用すると、新しい値を取得できます。
次のコードは、オブジェクトの変更を監視する方法を示しています。
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(); }
変更リスナーの登録解除
変更リスナーで通知を受信したくない場合は、ハンドラーの登録を解除します。 コードは、Realm オブジェクトのコレクションとコレクション プロパティの両方で同じです。 次のコードは、両方で変更リスナーの登録を解除する方法を示しています。
// 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;
通知制限の変更
4 レベルよりも深いネストされたドキュメントの変更では、変更通知はtriggerされません。
5 レベル以上の変更をリッスンする必要があるデータ構造がある場合は、次の回避策があります。
スキーマをリファクタリングしてネストを減らします。
ユーザーがデータを手動で更新できるようにするには、「push-to-refresh」のようなものを追加します。