在源列表中显示固定和可编辑的项目

Posted

技术标签:

【中文标题】在源列表中显示固定和可编辑的项目【英文标题】:Displaying fixed and editable items in a Source List 【发布时间】:2009-11-28 11:31:11 【问题描述】:

背景

我正在为我的应用程序创建一个源列表,我希望它的结构类似于 iTunes,包含两种类型的项目:

“固定”项目——这些项目不会改变,也不能移动——在顶部 下方的可编辑项目,可由用户更改 - 移动、重命名等(在 iTunes 示例中,例如播放列表和智能播放列表)

在我的 iTunes 类比中:

(来源:perspx.com)

到目前为止,我构建数据的方式如下:

我想要编辑的项目是“组”项目,形式为Group Core Data 实体。 源列表中的每个项目都表示为SourceListItem 常规 Objective-C 对象,以便我可以将每个项目与标题、图标、子项目等相关联 固定项当前由SourceListItem 实例表示,存储在我的控制器对象的数组中。

问题

我不确定如何将这两种类型的项目合并到源列表中,以便固定项目在顶部并且始终存在并且不会更改,而可编辑项目在底部并且可以移动并编辑。

这些是我迄今为止提出的想法:

将固定项添加到核心数据模型。这意味着我可以创建一个实体来表示源列表项,并将我的固定和可编辑项放置在这些实例中。然后这些可以绑定到带有数组/树控制器的大纲视图表列。但是,这意味着我必须创建一个新实体来表示源列表项,然后将Groups 与此同步。我还必须有某种方法只创建一次所有固定项目,如果任何持久存储文件发生问题,则不会显示固定项目。

将固定项与组项合并。虽然两者都存储在单独的数组中,但当大纲视图请求数据时,这可以在我的窗口的控制器中完成(如果采用NSOutlineViewDataSource 协议,而不是绑定)。然而,这意味着我必须为数组控制器中的每个组创建新的SourceListItems(将每个组与图标和其他属性相关联),存储这些,然后观察组数组控制器的更改以删除、添加或修改对组进行更改时的 SourceListItem 实例。

有人对我如何实现这个有更好的想法吗?

我希望我的应用程序与 OS X v10.5 兼容,因此我更喜欢依赖于安装 Snow Leopard 的任何解决方案。

【问题讨论】:

【参考方案1】:

我正在开发一个具有完全相同行为的应用程序,我是这样做的:

我的核心数据模型中有 5 个主要实体:

    AbstractItem - 一个抽象实体,具有所有项目共有的属性,如 nameweighteditable。还有两个关系:parent(与AbstractItem 的一对一关系)和children(与AbstractItem 的一对多关系,与parent 相反)。 Group - AbstractItem 的具体子实体。 Folder - AbstractItem 的具体子实体。向基本 Item 实体添加多对多关系。 SmartFolder - Folder 的具体子实体。添加二进制属性predicateData。覆盖Folder 的“items”关系访问器,以返回使用predicateData 属性定义的谓词执行提取请求的结果。 DefaultFolder - SmartFolder 的具体子实体。添加字符串属性identifier

对于“库”部分的项目,我插入 DefaultFolder 对象并给它们一个唯一标识符,以便我可以轻松检索它们并区分它们。我还给他们一个NSPredicate,它对应于他们应该显示的Items。例如,“音乐”DefaultFolder 将有一个谓词来检索所有音乐项目,“播客”DefaultFolder 将有一个谓词来检索所有播客项目,等等。

根级项目(“Library”、“Shared”、“Store”、“Genius”等)都是 Group 具有 nil 父项的项目。无法编辑的组和文件夹的editable 属性设置为NO

至于在大纲视图中实际获取这些内容,您必须自己实现NSOutlineViewDataSourceNSOutlineViewDelegate 协议。这里有太多的行为复杂性,无法通过NSTreeController 将其抽出。然而,在我的应用程序中,我在不到 200 行代码中获得了所有行为(甚至是拖放)(所以它并没有那么糟糕)。

【讨论】:

很好的答案,谢谢。然而,我对纯核心数据路由的主要关注是关于创建始终存在的“固定”项目(在你的情况下是库项目)——你是否只是在加载时测试它们是否已经在模型中如果没有,则创建它们? @Perspx - 因为我给了它们唯一标识符(@"Music"@"Podcasts" 等),所以我可以获取所有 DefaultFolders,检查我有哪些,然后创建我没有的不。 (简短回答:是的) AbstractItemweight 属性的用途是什么?还是仅针对您正在建模的数据? @jbrennan - 由于 CoreData 将所有内容都存储为集合,因此它不会保持顺序。我使用weight 属性来记住用户放置物品的顺序。权重越低,列表中的位置越高。列表中的第一件事的权重为零。每次用户在同一级别添加新的AbstractItem 或用户拖放时,都会动态重新计算此权重。 我还应该说我称它为“重量”,因为当我使用 Drupal 时就是这样称呼它的。也许“订单”可能是一个更好的名字。【参考方案2】:

不要仅仅为了支持视图而在数据集中注入废话。这不仅违背了 MVC 设计模式,而且给最重要的部分:用户数据的管理增加了不必要的复杂性(即“更多潜在的错误”)。

也就是说,在这种特殊情况下使用绑定是造成如此多摩擦的原因。为什么不完全避开绑定?我认为,使用 NSOutlineViewDataSource 协议,您走在正确的轨道上,但您做得还不够远。相反,完全依赖这个(仍然完全有效并且在某些方面更优越)协议。

您实际上是在用易于设置(和易于更改通知)换取对树结构的完全控制。

【讨论】:

是的,我认为你是对的;我只是认为绑定是一种潜在的实现方式。我确实更喜欢NSOutlineViewDataSource 协议的想法,但是像这样将数据拼凑在一起似乎有点笨拙,正如我所说,这也意味着我需要注意核心数据Group 实例的变化以反映这些变化SourceListItems 的数组 这没有什么不妥之处。在 Mac OS X 10.3 之前,这是唯一的方法(在 Cocoa 中)。也没有必要将所有内容集中在一起作为一个结构。您的组是根项目。每个组的孩子都是一个结果数组。没有问题,没有混乱,没有内疚。 :-)

以上是关于在源列表中显示固定和可编辑的项目的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Angular 中使字段可拖动和可编辑?

EditView不可编辑状态和可编辑状态动态切换 及 EditView的其它特效

如何在HTML / Javascript中创建可编辑的组合框?

在 swift 中使 URL 链接属性和可点击以及可编辑的 Textview

React.js 创建具有动态行数和可编辑列的表

如何使模型 id 在 asp mvc 中可插入和可编辑?