如何对Realm LinkingObjects中的元素重新排序?

时间:2019-07-14 19:58:52

标签: swift realm

我有一个Item数据类,每个Item有一个父项和许多子项,它们是parent属性中的LinkingObjects。 简化版:

@objcMembers class Item: Object {
    dynamic var title: String = ""
    dynamic var parent: Item?
    let children = LinkingObjects(fromType: Item.self, property: "parent")
}

我需要能够对孩子们重新排序,并坚持这一改变。似乎因为LinkingObjects是容器类型,所以这不可能吗?在这种情况下,您将如何建议我采用这种方法-我应该将children更改为普通的List<Item>,并且每次都仅以两种方式手动更新领域吗?有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

  

孩子出现的顺序很重要,因为用户希望根据他们首先要看的项目选择自己的排序。

这里的重要部分是您要控制“孩子出现的顺序”。如果您可以识别数据的“模型”和数据的“视图”之间的区别,那么您可以算出答案。请记住,Realm模型表示不受您的控制,您也不需要它。它如何存储在Realm数据库中不是您的问题。

实际上,当您请求LinkingObjects字段时,其结果可能是数据库查询的结果,而不是直接从表中提取。因此,字段中对象的顺序可能不一致,或者添加更多链接的对象可能导致多余的项目出现在结果中的任何地方。

正如您所说,重要的是孩子出现的顺序。这可以通过查询来控制。 LinkingObjects类型可让您直接查询,即可以调用:

item.children.sorted(byKeyPath: "title")

一个建议是在模型类型上添加扩展名,以为您处理排序,为所需的每种排序类型提供访问器,例如:

extension Item
{
  var childrenSortedByTitle: Results<Item>
  {
    return children.sorted(byKeyPath: "title")
  }
}

或者您可以使该函数带有布尔参数ascending以便在查询中使用。或者,您可以添加第二个查询以进行升/降。您可以为要作为排序依据的每个其他参数添加额外的查询。或者,您可以定义一个排序字段的枚举,并将其作为参数传递。这些方法中的哪一种最适合您。但是绝对值得将查询详细信息隐藏在类扩展本身(IMHO)中。