Multiple NSArrayControllers bound to an NSObjectController

  • I have a model object that has a name and an array attribute. I have an
    array of these model objects bound to an NSArrayController. I can then feed
    another NSArrayController with the array attribute of each model object to
    create  a master-detail inteface. I have one NSTableView that displays the
    model objects' names and then another NSTableView that shows the model
    object's array properties.

    This works fine. However, as I have been extending this interface
    (incorporating drag 'n drop), I have come up against design issues,
    particularly in the area of undo. I have been creating a lot of code to make
    sure that when I make a change to an NSArrayController's arrangedObjects
    array that any changes which are undone affect the correct model object's
    array. I have to keep track of sortDescriptors, insertion and deletion
    indexes, etc.

    As a consequence, I had an idea. What happened if my model object also had
    an NSArrayController in code. When I change selection in the array of my
    model objects, the detail NSTableView is connected to my model object's
    NSArrayController. I feel like this would obviate a lot of management issues
    I am currently experiencing.

    My array of model objects is bound to an NSArrayController. I thought I
    could use an NSObjectController and bind it to the
    selection.controllerkeyPath of the NSArrayController that controls my
    model objects and use that
    to populate my NSTableView, but it is not working.

    Does anyone have any insight? I can include a test session.

    Boris
  • On 9-Nov-07, at 1:52 AM, Boris Yeltsin wrote:

    > I have a model object that has a name and an array attribute. I have
    > an
    > array of these model objects bound to an NSArrayController. I can
    > then feed
    > another NSArrayController with the array attribute of each model
    > object to
    > create  a master-detail inteface. I have one NSTableView that
    > displays the
    > model objects' names and then another NSTableView that shows the model
    > object's array properties.

    To clarify what follows, I will recount my understanding of the
    situation: you have a Model object which has a to-many relationship
    called 'properties', where each element is a Property object with
    attributes corresponding to the columns of your detail table view.

    > This works fine. However, as I have been extending this interface
    > (incorporating drag 'n drop), I have come up against design issues,
    > particularly in the area of undo. I have been creating a lot of code
    > to make
    > sure that when I make a change to an NSArrayController's
    > arrangedObjects
    > array that any changes which are undone affect the correct model
    > object's
    > array. I have to keep track of sortDescriptors, insertion and deletion
    > indexes, etc.

    I think a better approach is to directly effect the underlying to-many
    relationship 'properties'.  If you have bound the content of your
    detail array controller to the 'properties' of the selected Model then
    any mutation of that relationship will be reflected in the array
    controller.  To do this, have your drop method perform its array
    mutations on

      [selectedModel mutableArrayValueForKey:@"properties"].

    Implementing undo support is simplified by adding a category on
    NSMutableArray with methods such as :

      - (void) insertObjects:(NSArray *)objects atIndexes:(NSIndexSet
    *)indices undo:(NSUndoManager *)undo
        {
          [[undo prepareWithInvocationTarget:self]
    removeObjectsAtIndexes:indices undo:undo];
          [self insertObjects:objects atIndexes:indices];
        }

    Performing an undo-able move operation can then be written along the
    lines of...

      NSMutableArray *sourceProperties = [sourceModel
    mutableArrayValueForKey:@"properties"];
      NSMutableArray *targetProperties = [targetModel
    mutableArrayValueForKey:@"properties"];
      NSArray *movingProperties = [sourceProperties
    objectsAtIndexes:sourceIndices];
      [sourceProperties removeObjectsAtIndexes:sourceIndices
    undo:myUndoManager];
      [targetProperties insertObjects:movingProperties
    atIndexes:targetIndices undo:myUndoManager];

    > As a consequence, I had an idea. What happened if my model object
    > also had
    > an NSArrayController in code. When I change selection in the array
    > of my
    > model objects, the detail NSTableView is connected to my model
    > object's
    > NSArrayController. I feel like this would obviate a lot of
    > management issues
    > I am currently experiencing.
    >
    >
    > My array of model objects is bound to an NSArrayController. I
    > thought I
    > could use an NSObjectController and bind it to the
    > selection.controllerkeyPath of the NSArrayController that controls my
    > model objects and use that
    > to populate my NSTableView, but it is not working.
    >
    >
    > Does anyone have any insight? I can include a test session.

    I would resist the temptation to add controllers to your model
    objects...

    > Boris

    Cheers,
    dave
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today