Using representedObject to bind ArrayController content


#1

I have a document-based app with a windowController that chooses the appropriate viewController based on a segmented control choice. Each view will update part of the data model. I had difficulty figuring out how to bind the arrayController’s content array to the data model in the document, but finally hit on the viewController’s representedObject property. I set representedObject of the viewController to the appropriate document array, and bind the content array of the arrayController to File’s Owner.representedObject. This works well going from the document array to the view (the contents of the array appear in the user interface), but any changes made to those contents in the user interface never make it back to the document array, and none of the document array’s methods get called (updating, notifications, etc.) All the document support stuff that is supposed to happen automatically, doesn’t.

I thought the representedObject would be the object, not a copy of it - and IT is getting updated. But the model remains untouched. I can, of course, access the document directly in the viewController code, and update its array as I update the array controllers, but that kind of messes up the whole model-view-controller thing! Anyway, isn’t keeping the two arrays in sync the reason one uses an arrayController?

Any help would be appreciated. I really thought I had it, until I added undo manager and file saving and nothing ever registered in the menus!

The views are defined in the WindowController:

[code]-(void) windowWillLoad
{
viewControllers = [[NSMutableArray alloc] init];

ManagingViewController *vc;

vc=[[RecipeViewController alloc] init];
[vc setRepresentedObject:[[self document] recipes]];
[viewControllers addObject:vc];
indexRecipeView=0;


 vc=[[GroupViewController alloc] init];
[vc setRepresentedObject:[[self document] groups]];
 [viewControllers addObject:vc];
 indexGroupView=1;
 
 vc=[[IndexViewController alloc] init];
 [viewControllers addObject:vc];
 indexIndexView=2;

}
[/code]
Here’s my createRecipe method. Parts of it will look very familiar, I’m sure :slight_smile:

[code]- (IBAction)createRecipe:(id)sender
{
NSWindow *w = [recipeTable window];

// try and end any editing that is taking place
BOOL editingEnded = [w makeFirstResponder:w];
if (!editingEnded) {
    NSLog(@"Unable to end editing");
    return;
}
NSUndoManager *undo = [self undoManager];
//Has an edit occurred already in this event?
if ([undo groupingLevel] > 0) {
    //close the last group
    [undo endUndoGrouping];
    //open a new group
    [undo beginUndoGrouping];
}
//Create the object

CBIRecipe *r = [recipeController newObject];

//add to current array of 'recipeController' 
[recipeController insertObject:r atArrangedObjectIndex:[self.representedObject count]];

[recipeController setSelectedObjects:[NSArray arrayWithObject:r]];


//re-sort in case user has sorted a column
[recipeController rearrangeObjects];

//get the sorted array
NSArray *a = [recipeController arrangedObjects];

//find the object just added
NSUInteger row =[a indexOfObjectIdenticalTo:r];

[recipeTable editColumn:0 row:row withEvent:nil select:YES];

}
[/code]