0

这应该很容易,能有多难。

我有一个基于文档的核心数据应用程序,具有非常简单的数据模型。

我有一个“节点”实体,它与自身具有父/子关系,由 NSTreeController 控制,并通过 NSOutlineView 查看。“节点”还与另一个由 NSArrayController 管理的实体类型“nodeProperties”具有非可选(对一个)关系。我有两个实体的 NSManagedObject 子类。我的文档类具有绑定到树控制器和数组控制器实例的出口。

我的问题是如何确保当大纲视图中的用户界面操作创建一个新的“节点”时,它与合适的(预先存在的)nodeProperties 对象的关系被填充。

我尝试过/考虑过的方法:

  1. 让树控制器创建“节点”(从其 add:、addChild: 操作)并在“节点”子类 awakeFromInsert 方法中填充与 nodeProperties 对象的关系。问题是我找不到从“节点”的 awakeFromInsert 中访问任何 nodeProperties 对象的方法。“适当的”nodeProperties 对象可从文档类中的一个方法获得,但从节点 awakeFromInsert 方法访问文档对象似乎违反了 MVC 的原则,并且我读过共享文档对象在拖动中并不总是安全的和删除操作(在我的例子中,它也创建了一个新的节点对象)

  2. 在文档类中编写 add: 和 addChild: 操作方法,并从最终用户操作而不是树控制器调用这些方法(我的拖放支持也在文档类中)。然后从这些方法中调用树控制器中的 add: 和 addChild: 方法,然后在新创建的节点上设置 nodeProperties 关系。问题是我不知道如何让树控制器给我一个新创建的节点的引用?我尝试使用 selectedObjects 方法获取父节点,然后比较添加前后的父子节点以获取新节点。但是此时儿童内容并没有改变——也许是延迟更新?

  3. 作为 2 的变体,根本不使用树控制器 add:/addChild: 方法,而是在文档中创建节点实体对象 add:/addChild: 方法,使用树控制器 selectedOjects 来获取父级。我真的不喜欢这样,因为它似乎在树控制器后面做一些事情,而且我必须 setContent: 每次创建根对象时。

  4. 我已经考虑过观察新创建节点的创建的可能性,但我不知道要观察什么来实现这一点。

以前一定有人做过这样的事情 - 但我拖网无济于事。非常欢迎所有帮助、建议和指导。

4

1 回答 1

0

好的,经过大量的拖网和实验,答案是 3 的变体。文档创建新节点,填充其强制关系,在 add 和 addChild 操作方法中,然后使用该方法将节点插入树控制器

NSTreeController insertObject:atArrangedObjectIndexPath:

对于那些感兴趣的人,这是我在文档类中的 addChild 方法。它有一些来自我的数据模型的细节

- (IBAction)addChildAction:(id)sender
{
    NSArray *indexPaths = [nodeTreeController selectionIndexPaths];
    NSArray *selectedObjects = [nodeTreeController selectedObjects];
    for (NSUInteger i = 0; i < [indexPaths count]; i++)
    {
        QVXpandNode *parentNode = [selectedObjects objectAtIndex:i];
        if ((parentNode) && ([parentNode.isMaster boolValue])) // can only add nodes under the master node
        {
            QVXpandNode *createdNode = [self createPopulatedNode];
            // Dont belelieve below is safe when >1 selected,
            // since adding a new node will result in the tree paths changing?
            // Hmmm but I do want to support multiple selection addition??
            [nodeTreeController
                insertObject:createdNode
                atArrangedObjectIndexPath:[[indexPaths
                    objectAtIndex:i] indexPathByAddingIndex:[parentNode.children count]]];
        }
    }
}

您会看到,如果在调用操作之前选择了 >1 行,我不确定是否将第二个和以后的孩子放在正确的路径上。

由于需要计算最后一个索引路径值,addSibling 方法稍微复杂一些,但在其他方面类似。如果有人想查看它,我可以重现它,但是在新树节点中填充强制关系的关键是在文档类中执行此操作,然后准确地告诉树控制器您要在树中的哪个位置插入它。

于 2014-06-24T22:21:33.097 回答