创建嵌入式对象
要创建嵌入式对象,请将嵌入式对象的实例分配给父对象的属性:
例子
在以下 CreateContact示例中,我们创建一个带有嵌入式Address对象的新Contact对象。
CreateContact 组件将执行以下操作:
创建表示联系人姓名和解决详细信息的React 状态 变量。
通过调用该组件中的
useRealm()钩子来访问打开的 Realm 实例。创建执行写事务的组件方法
submitContact(),以根据联系人姓名和地址的TextInput值创建新的Address嵌入式对象和Contact父对象。在“提交联系人”按钮上添加一个用于调用
submitContact()的onPress事件。
1 const CreateContact = () => { 2 const [name, setContactName] = useState(''); 3 const [street, setStreet] = useState(''); 4 const [city, setCity] = useState(''); 5 const [country, setCountry] = useState(''); 6 const [postalCode, setPostalCode] = useState(''); 7 const realm = useRealm(); 8 9 const submitContact = () => { 10 // Create a Contact within a write transaction 11 realm.write(() => { 12 // Create an embedded Address object 13 const address = { 14 street, 15 city, 16 country, 17 postalCode, 18 }; 19 20 realm.create('Contact', { 21 _id: new Realm.BSON.ObjectID(), 22 name, 23 // Embed the address in the Contact object 24 address, 25 }); 26 }); 27 }; 28 return ( 29 <View> 30 <TextInput value={name} onChangeText={text => setContactName(text)} /> 31 <TextInput value={street} onChangeText={text => setStreet(text)} /> 32 <TextInput value={city} onChangeText={text => setCity(text)} /> 33 <TextInput value={country} onChangeText={text => setCountry(text)} /> 34 <TextInput 35 value={postalCode} 36 onChangeText={text => setPostalCode(text)} 37 /> 38 <Button 39 title='Submit Contact' 40 onPress={submitContact} 41 /> 42 </View> 43 ); 44 };
查询嵌入式对象属性的集合
您可以使用点表示法,根据嵌入式对象的属性值对对象集合进行过滤或排序。
例子
在以下 ContactList 示例中,我们筛选和查询嵌入的 Address 对象。
ContactList 组件将执行以下操作:
通过将
Contact类传递给useQuery钩子,查询所有联系人。通过在查询
"name == 'John Smith'"上传递collection.filtered()来筛选名称为 "John Smith" 的联系人。使用点表示法检索联系人的街道地址。
1 const ContactList = ({postalCode}) => { 2 // Run the `.filtered()` method on all the returned Contacts to get 3 // contacts with a specific postal code. 4 const contactsInArea = useQuery( 5 Contact, 6 contacts => { 7 return contacts.filtered(`address.postalCode == '${postalCode}'`); 8 }, 9 [postalCode], 10 ); 11 12 if (contactsInArea.length) { 13 return ( 14 <> 15 <FlatList 16 testID='contactsList' 17 data={contactsInArea} 18 renderItem={({item}) => { 19 <Text>{item.name}</Text>; 20 }} 21 /> 22 </> 23 ); 24 } else { 25 return <Text>No contacts found in this area.</Text>; 26 } 27 };
1 const ContactList = ({postalCode}: {postalCode: string}) => { 2 // Run the `.filtered()` method on all Contact objects to get 3 // contacts with a specific postal code. 4 const contactsInArea = useQuery(Contact, contacts => { 5 return contacts.filtered(`address.postalCode == '${postalCode}'`); 6 }); 7 8 if (contactsInArea.length) { 9 return ( 10 <> 11 <FlatList 12 data={contactsInArea} 13 renderItem={({item}) => { 14 <Text>{item.name}</Text>; 15 }} 16 /> 17 </> 18 ); 19 } else { 20 return <Text>No contacts found in this area.</Text>; 21 } 22 };
更新嵌入式对象属性
若要更新嵌入式对象中的属性,请在写事务中修改该属性。
例子
在以下 UpdateContact 示例中,我们将更新一个嵌入式 Address 对象的 street 属性。
UpdateContact 组件将执行以下操作:
创建表示联系人新街道地址的 React 状态 变量。
通过将
Contact类传递给useQuery钩子来查询所有联系人,并筛选出与作为属性传递到组件的名称相匹配的联系。通过调用该组件中的
useRealm()钩子来访问打开的 Realm 实例。创建用于执行写事务的组件方法
updateStreet(),并将联系人的街道地址设置为street状态变量的值。呈现一个显示并更改
street状态变量的TextInput。在
'Update Street Address'按钮上添加一个用于调用updateStreet()的onPress事件。
1 // Find the contact you want to update 2 const UpdateContact = ({contactId}) => { 3 const [street, setStreet] = useState(''); 4 const contact = useObject(Contact, contactId); 5 const realm = useRealm(); 6 7 const updateStreet = () => { 8 // Modify the property of the embedded Address object in a write transaction 9 realm.write(() => { 10 // Update the address directly through the contact 11 contact.address.street = street; 12 }); 13 }; 14 15 return ( 16 <View> 17 <Text>{contact.name}</Text> 18 <TextInput 19 value={street} 20 onChangeText={setStreet} 21 placeholder='Enter New Street Address' 22 /> 23 <Button 24 onPress={updateStreet} 25 title='Update Street Address' 26 /> 27 </View> 28 ); 29 };
1 // Find the contact you want to update 2 const UpdateContact = ({contactId}: {contactId: Realm.BSON.ObjectId}) => { 3 const [street, setStreet] = useState(''); 4 const contact = useObject(Contact, contactId); 5 const realm = useRealm(); 6 7 const updateStreet = () => { 8 // Modify the property of the embedded Address object in a write transaction 9 realm.write(() => { 10 // Update the address directly through the contact 11 contact!.address.street = street; 12 }); 13 }; 14 15 return ( 16 <View> 17 <Text>{contact!.name}</Text> 18 <TextInput 19 value={street} 20 onChangeText={setStreet} 21 placeholder='Enter New Street Address' 22 /> 23 <Button 24 onPress={updateStreet} 25 title='Update Street Address' 26 /> 27 </View> 28 ); 29 };
覆盖嵌入式对象
要覆盖嵌入式对象,请在写事务中将一方的嵌入式对象属性重新分配给新实例。
例子
在以下 OverwriteContact 示例中,我们覆盖了一个嵌入式Address 对象。
OverwriteContact 组件将执行以下操作:
创建代表联系人新地址的 React 状态 变量。
通过将
Contact类传递给useQuery钩子来查询所有联系人,并筛选出与作为属性传递到组件的名称相匹配的联系。通过调用该组件中的
useRealm()钩子来访问打开的 Realm 实例。创建用于执行写事务的组件方法
updateAddress(),并创建一个新的Address对象来覆盖Contact对象中的现有地址。呈现
TextInput元件,显示并变更新地址的状态变量。在
'Overwrite Address'按钮上添加一个用于调用updateAddress()的onPress事件。
1 const OverwriteContact = ({contactId}) => { 2 const [street, setStreet] = useState(''); 3 const [city, setCity] = useState(''); 4 const [country, setCountry] = useState(''); 5 const [postalCode, setPostalCode] = useState(''); 6 const contact = useObject(Contact, contactId); 7 const realm = useRealm(); 8 9 const updateAddress = () => { 10 realm.write(() => { 11 // Within a write transaction, overwrite the embedded object with the new address 12 const address = { 13 street, 14 city, 15 country, 16 postalCode, 17 }; 18 19 contact.address = address; 20 }); 21 }; 22 return ( 23 <View> 24 <Text>{contact.name}</Text> 25 <Text>Enter the new address:</Text> 26 <TextInput 27 value={street} 28 onChangeText={setStreet} 29 placeholder='Street' 30 /> 31 <TextInput value={city} onChangeText={setCity} placeholder='City' /> 32 <TextInput 33 value={country} 34 onChangeText={setCountry} 35 placeholder='Country' 36 /> 37 <TextInput 38 value={postalCode} 39 onChangeText={setPostalCode} 40 placeholder='Postal Code' 41 /> 42 <Button 43 onPress={updateAddress} 44 title='Overwrite Address' 45 /> 46 </View> 47 ); 48 };
1 const OverwriteContact = ({ 2 contactId, 3 }: { 4 contactId: Realm.BSON.ObjectId; 5 }) => { 6 const [street, setStreet] = useState(''); 7 const [city, setCity] = useState(''); 8 const [country, setCountry] = useState(''); 9 const [postalCode, setPostalCode] = useState(''); 10 const contact = useObject(Contact, contactId); 11 const realm = useRealm(); 12 13 const updateAddress = () => { 14 realm.write(() => { 15 // Within a write transaction, overwrite the embedded object with the new address 16 const address = { 17 street, 18 city, 19 country, 20 postalCode, 21 }; 22 23 contact!.address = address; 24 }); 25 }; 26 27 return ( 28 <View> 29 <Text>{contact!.name}</Text> 30 <Text>Enter the new address:</Text> 31 <TextInput 32 value={street} 33 onChangeText={setStreet} 34 placeholder='Street' 35 /> 36 <TextInput value={city} onChangeText={setCity} placeholder='City' /> 37 <TextInput 38 value={country} 39 onChangeText={setCountry} 40 placeholder='Country' 41 /> 42 <TextInput 43 value={postalCode} 44 onChangeText={setPostalCode} 45 placeholder='Postal Code' 46 /> 47 <Button 48 onPress={updateAddress} 49 title='Overwrite Address' 50 /> 51 </View> 52 ); 53 };
删除嵌入式对象
Realm 对嵌入式对象使用级联删除要删除嵌入式对象,请删除嵌入式对象的父对象。
例子
在以下 DeleteContact 示例中,我们删除了一个嵌入式对象及其父对象。
DeleteContact 组件将执行以下操作:
通过将
Contact类传递给useQuery钩子,查询所有联系人。Contact筛选与作为属性传递到组件的名称相匹配的 对象。通过调用该组件中的
useRealm()钩子来访问打开的 Realm 实例。创建用于执行写事务的组件方法
deleteContact(),并调用Realm.delete()来删除Contact对象。在用于调用
deleteContact()的“Delete Contact”(删除联系人)按钮上添加 onPress 事件。
1 const ContactInfo = ({contactCity, postalCode}) => { 2 const realm = useRealm(); 3 const parentsToDelete = useQuery( 4 Contact, 5 contacts => { 6 return contacts.filtered(`address.city == '${contactCity}'`); 7 }, 8 [contactCity], 9 ); 10 const embeddedToDelete = useQuery( 11 Contact, 12 contacts => { 13 return contacts.filtered(`address.postalCode == '${postalCode}'`); 14 }, 15 [postalCode], 16 ); 17 18 const deleteParentObject = () => { 19 realm.write(() => { 20 // Delete all objects that match the filter. 21 // Also deletes embedded objects. 22 realm.delete(parentsToDelete); 23 }); 24 }; 25 26 const deleteEmbeddedObject = () => { 27 realm.write(() => { 28 embeddedToDelete.forEach(contact => { 29 // Delete just the embedded object. 30 realm.delete(contact.address); 31 }); 32 }); 33 }; 34 35 return ( 36 <View> 37 <Text testID='contactCityText'>{contactCity}</Text> 38 <Button 39 onPress={deleteParentObject} 40 title='Delete Contact' 41 /> 42 <Button 43 onPress={deleteEmbeddedObject} 44 title='Delete Address' 45 /> 46 </View> 47 ); 48 };
1 type ContactInfoProps = { 2 contactCity: string; 3 postalCode: string; 4 }; 5 6 const ContactInfo = ({contactCity, postalCode}: ContactInfoProps) => { 7 const parentsToDelete = useQuery(Contact, contacts => { 8 return contacts.filtered(`address.city == '${contactCity}'`); 9 }); 10 const embeddedToDelete = useQuery(Contact, contacts => { 11 return contacts.filtered(`address.postalCode == '${postalCode}'`); 12 }); 13 const realm = useRealm(); 14 15 const deleteParentObject = () => { 16 realm.write(() => { 17 // Delete all objects that match the filter. 18 // Also deletes embedded objects. 19 realm.delete(parentsToDelete); 20 }); 21 }; 22 23 const deleteEmbeddedObject = () => { 24 realm.write(() => { 25 embeddedToDelete.forEach(contact => { 26 // Delete just the embedded object. 27 realm.delete(contact.address); 28 }); 29 }); 30 }; 31 32 return ( 33 <View> 34 <Text testID='contactCityText'>{contactCity}</Text> 35 <Button 36 onPress={deleteParentObject} 37 title='Delete Contact' 38 /> 39 <Button 40 onPress={deleteEmbeddedObject} 41 title='Delete Address' 42 /> 43 </View> 44 ); 45 };