【问题标题】:Deleting items in one-to-many relation in Realm在Realm中删除一对多关系中的项目
【发布时间】:2017-04-28 11:58:06
【问题描述】:

以下代码适用于添加新的ItemLists 和将新的Itemss 添加到ItemLists。我遇到的问题是从列表中删除所有项目。换句话说,我有一个按钮 (deleteAllItems),它应该从所选列表中删除所有项目,但我现在拥有它的方式会删除 Realm 中的 ALL Items无论是哪个列表拥有它们。

创建多个ItemLists 的正确方法是什么,它将包含多个Items 并能够从某个列表中删除所有Items?

ItemList 对象:

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)
            }
        }
    }
}

【问题讨论】:

    标签: ios swift realm one-to-many


    【解决方案1】:

    在您的 deleteAllItems 函数中,您应该过滤它们。不过滤这是预期的行为,因为您只指定了一个对象类,因此 Realm 显然会删除与该类匹配的所有对象。

    如果您想从 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 应该在类中的函数外部声明,或者您也可以在函数内部声明它,具体取决于您实际想要实现的目标。 此外,此实现假定您的 listNames 和 productNames 是唯一的。

    【讨论】:

    • 非常感谢您的帮助。
    • 仅供参考 - 我必须对 for in 循环进行以下更改才能使其正常工作。 for item in (listToDelete?.items)!。 @Dávid Pásztor - 快速提问,"listName = %@" 中的 = %@ 有什么作用?
    • 我已经更新了我的答案以安全地展开列表,你不应该使用强制展开,因为如果列表不存在,你的代码将会崩溃。 “%@ 是对象值的 var arg 替换——通常是字符串、数字或日期”——来自Apple's Predicate Format String Syntax document
    猜你喜欢
    • 2015-02-21
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2019-04-27
    • 2015-01-06
    • 1970-01-01
    相关资源
    最近更新 更多