在 Realm 中删除一对多关系的项目
Deleting items in one-to-many relation in Realm
以下代码可以很好地添加新的 ItemList
s 和向 ItemList
s 添加新的 Items
s。我遇到的问题是从列表中删除所有项目。换句话说,我有一个按钮(deleteAllItems
),它应该从所选列表中删除所有项目,但我现在拥有它的方式删除了 ALL Item
s 在 Realm
中,无论哪个列表拥有它们。
创建包含多个 Item
的多个 ItemList
并能够从特定列表中删除所有 Item
的正确方法是什么?
项目列表对象:
class ItemList: Object {
dynamic var listName = ""
dynamic var createdAt = NSDate()
let items = List<Item>()
}
项目对象:
class Item: Object {
dynamic var productName = ""
dynamic var createdAt = NSDate()
}
主控制器:
class ViewController: UIViewController, UITableViewDataSource{
@IBOutlet weak var tableListOfItems: UITableView!
@IBOutlet weak var inputProductName: UITextField!
@IBOutlet weak var inputListName: UITextField!
var allItems : Results<Item>!
override func viewDidLoad() {
super.viewDidLoad()
updateData()
}
@IBAction func addNewList(_ sender: Any) {
let list = ItemList()
list.listName = inputListName.text!
try! realm.write {
realm.add(list)
}
}
@IBAction func addNewItem(_ sender: Any) {
let newItem = Item()
newItem.productName = inputProductName.text!
let list = realm.objects(ItemList.self).filter("listName = 'List Name Here'").first!
try! realm.write {
list.items.append(newItem)
updateData()
}
}
func updateData(){
allItems = realm.objects(Item.self)
tableListOfItems.reloadData()
}
/// This deletes every Item in Realm which is not what
/// I want. I want to delete only items that belong to
/// a certain list. I tried...
/// let list = realm.objects(ItemList.self).filter("listName = 'Default List'").first!
/// list.items.removeAll()
@IBAction func deleteAllItems(_ sender: Any) {
try! realm.write {
realm.delete(realm.objects(Item.self))
updateData()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
let data = allItems[indexPath.row]
cell.textLabel?.text = data.productName
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete{
if let item = allItems?[indexPath.row] {
try! realm.write {
realm.delete(item)
}
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
}
}
}
}
在您的 deleteAllItems 函数中,您应该过滤它们。如果不进行过滤,这是预期的行为,因为您只指定了一个对象 class,所以 Realm 显然会删除所有匹配 class.
的对象
如果您想从 Realm 本身删除列表中包含的所有项目,但保留空列表,您需要按以下方式更改 deleteAllItems 函数:
@IBAction func deleteAllItems(_ sender: Any) {
guard let listToDelete = realm.objects(ItemList.self).filter("listName = %@",listNameToDelete).first else { return }
try! realm.write {
for item in listToDelete.items {
realm.delete(realm.objects(Item.self).filter("productName = %@", item.productName).first)
updateData()
}
}
}
listNameToDelete 应该在 class 中的函数外部声明,或者您也可以在函数内部声明它,具体取决于您实际想要实现的目标。
此外,此实现假定您的 listNames 和 productNames 是唯一的。
以下代码可以很好地添加新的 ItemList
s 和向 ItemList
s 添加新的 Items
s。我遇到的问题是从列表中删除所有项目。换句话说,我有一个按钮(deleteAllItems
),它应该从所选列表中删除所有项目,但我现在拥有它的方式删除了 ALL Item
s 在 Realm
中,无论哪个列表拥有它们。
创建包含多个 Item
的多个 ItemList
并能够从特定列表中删除所有 Item
的正确方法是什么?
项目列表对象:
class ItemList: Object {
dynamic var listName = ""
dynamic var createdAt = NSDate()
let items = List<Item>()
}
项目对象:
class Item: Object {
dynamic var productName = ""
dynamic var createdAt = NSDate()
}
主控制器:
class ViewController: UIViewController, UITableViewDataSource{
@IBOutlet weak var tableListOfItems: UITableView!
@IBOutlet weak var inputProductName: UITextField!
@IBOutlet weak var inputListName: UITextField!
var allItems : Results<Item>!
override func viewDidLoad() {
super.viewDidLoad()
updateData()
}
@IBAction func addNewList(_ sender: Any) {
let list = ItemList()
list.listName = inputListName.text!
try! realm.write {
realm.add(list)
}
}
@IBAction func addNewItem(_ sender: Any) {
let newItem = Item()
newItem.productName = inputProductName.text!
let list = realm.objects(ItemList.self).filter("listName = 'List Name Here'").first!
try! realm.write {
list.items.append(newItem)
updateData()
}
}
func updateData(){
allItems = realm.objects(Item.self)
tableListOfItems.reloadData()
}
/// This deletes every Item in Realm which is not what
/// I want. I want to delete only items that belong to
/// a certain list. I tried...
/// let list = realm.objects(ItemList.self).filter("listName = 'Default List'").first!
/// list.items.removeAll()
@IBAction func deleteAllItems(_ sender: Any) {
try! realm.write {
realm.delete(realm.objects(Item.self))
updateData()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
let data = allItems[indexPath.row]
cell.textLabel?.text = data.productName
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete{
if let item = allItems?[indexPath.row] {
try! realm.write {
realm.delete(item)
}
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
}
}
}
}
在您的 deleteAllItems 函数中,您应该过滤它们。如果不进行过滤,这是预期的行为,因为您只指定了一个对象 class,所以 Realm 显然会删除所有匹配 class.
的对象如果您想从 Realm 本身删除列表中包含的所有项目,但保留空列表,您需要按以下方式更改 deleteAllItems 函数:
@IBAction func deleteAllItems(_ sender: Any) {
guard let listToDelete = realm.objects(ItemList.self).filter("listName = %@",listNameToDelete).first else { return }
try! realm.write {
for item in listToDelete.items {
realm.delete(realm.objects(Item.self).filter("productName = %@", item.productName).first)
updateData()
}
}
}
listNameToDelete 应该在 class 中的函数外部声明,或者您也可以在函数内部声明它,具体取决于您实际想要实现的目标。 此外,此实现假定您的 listNames 和 productNames 是唯一的。