Another bindings conundrum (editing a to-many relationship through an NSArrayController)
Another bindings conundrum (editing a to-many relationship through an NSArrayController)
- Subject: Another bindings conundrum (editing a to-many relationship through an NSArrayController)
- From: Luke Evans <email@hidden>
- Date: Thu, 17 Mar 2011 11:01:28 -0700
After a hiatus from Cocoa bindings, I'm back trying to create the following
kind of UI on top of a Core Data model:
- A master table of SalesRep entities, which have a name, manager and
importantly a to-many relationship to Territories
- An NSTextFieldCell subclass for this Territories property with a formatter
that lists the Territory names and an ellipsis button that launches a picker
window that should edit the relationship (rather than text editing).
The column for Territories in the master SalesRep table is bound so that
cell values should be the relationship set.
Things are working to a point, but not quite in respect to how I'm using
this relationship...
When the ellipsis button is pressed on the Territories cell, the picker
(which is a classic two list picker with available and selected
lists/tables) is commissioned. The "available" list gets its values happily
by having an NSArrayController connected to the Territory entities. This
works great. The "selected" list has another NSArrayController for which I
bind its "contentSet" to the objectValue of the cell (which should be the
relationship set for the Territories).
Now, things seemed to be working fine, the picker UI popped up, and as I
selected Territories in the picker, the cell formatter showed the names of
the selected set. However, I found that the underlying model relationship
was not being updated, and rediscovered that the cell's objectValue is
actually a copy of the value passed to the cell (i.e. from the binding of
the column). I thought this would be a simple fix: override setObjectValue
and punt the original value (which is indeed a relationship set) into the
cell's representedObject, then use representedObject in the binding to
contentSet on my list controller. Annoyingly, while I can see this object
is consistently an *_NSFaultingMutableSet* and this is what is being bound
to by 'selected territories' controller, which also seems to add and remove
Territories from this set (via the controller's -addObjects and
-removeObjects), none of the changes get reflected on the underlying
SalesRep model object's territories relationship. When I close the picker,
none of the changes I've apparently made actually 'stick'.
A corollary issue with my 'fix', is that the cell's formatter still uses the
cell objectValue, which still appears to be a copy of the relationship set
and not the NSFaultingMutableSet (which I presume to be the real
relationship per the foregoing).
Anyway, in short, I'm wondering what the binding wiring for this sort of
thing is supposed to be. I'm trying to achieve a certain amount of
generality for my ellipsis button cell subclass and its associated picker,
and so want these items to pick up their relationship object in as natural a
way as possible (i.e. I don't want to write code in these classes that knows
anything special about SalesRep managed objects).
Perhaps there's a nice Apple sample somewhere that demonstrates a similar
pattern, but most examples I've seen are either classic master-detail UIs
when editing to-many relationships.
Hints and tips gratefully received as otherwise I can see this turning into
a mammoth tracing/head-scratching exercise to try to determine where I've
deviated from the canon enough to get myself into this situation. The one
problem with loosely-bound patterns like bindings is that you don't get much
help when you step away from the correct (designed/tested) use patterns.
Cheers
-- Luke
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden