FROM : David Spooner
DATE : Fri Nov 09 17:19:04 2007
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
DATE : Fri Nov 09 17:19:04 2007
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
| Related mails | Author | Date |
|---|---|---|
| Boris Yeltsin | Nov 9, 09:52 | |
| David Spooner | Nov 9, 17:19 |






Cocoa mail archive

