Re: bindings when used with external datasources?
Re: bindings when used with external datasources?
- Subject: Re: bindings when used with external datasources?
- From: Gwynne <email@hidden>
- Date: Sat, 12 Jun 2004 16:07:44 -0400
On Jun 12, 2004, at 3:05 PM, Theodore Petrosky wrote:
As an example, if I have a tableView, it is populated
by querying the database (which creates the
datasource), I have to watch if a row is updated and
create the sql for that row to update the db. Keep in
mind that I have many users accessing this db at the
same time. When the db gets updated, postgresql sends
our a notification to all connected users that are
looking at this data to trigger the screen updata.
Concurrency is important to me.
So the question is.. am I missing something here? does
anyone have an example of using these key bindings
that is accessing an external database (or even a
conversation on how it would be great to use the key
bindings...)?
Thanks, I am a complete newbie with bindings and maybe
I am just missing some point.
I run a bit of a risk of making a fool of myself here, since I'm almost
as new to bindings as you are; I've used them in only one project so
far. However, the concepts aren't that complicated once you work with
them, in my small experience.
It can be honestly said that Mark Stratman is right: doing what your
want with bindings requires more than the minimal functionality
thereof, and so as a newcomer to bindings you should probably go with
the traditional hand-made controller model. Bindings would provide
future expansion coverage for your problem, but at the cost of a
somewhat steep initial implementation curve. For the brave souls among
us, I do provide a view of how I believe implementing this could be
done :).
Bindings are theoretically the ultimate (or nearly so) expression of
the MVC coding paradigm. In your example, the View object is the table
view, the Model object is your database, and the Controller is one of
the NSControllers, probably NSArrayController. At this point, you have
two options. You can either create a Model object that provides the
interface between the controller and your database, or you could
subclass NSArrayController to use the database itself as the array. The
latter is probably more complicated so early in the learning process
:).
Let's assume that you create a Model object to handle the mediation.
The Model object should provide accessors and modifiers (and optionally
validators) for each piece of data that can be set in a given row.
Since this is a database interface, the object should also store and
provide an accessor (but NOT modifier) for a unique row ID (or whatever
your primary key is). Keep in mind that this Model object represents a
SINGLE row displayed on screen and stored in the database. The
accessors should query the database and/or cached data, and the
modifiers should run the UPDATE queries. Remember, as described in the
Key-Value Coding document: do NOT validate in modifiers (called setters
by the KVC docs); do that in validators.
Now you need an array which holds instances of this Model object for
every row to be shown. You can place this in the application delegate,
whereever, as long as it can be accessed somewhere from the nib. It
doesn't necessarily have to be an NSArray specifically, it can be an
NSDictionary keyed by the unique row IDs. There just needs to be an
accessor for it, and it of course needs to be mutable.
We have our Model. Create an instance of NSArrayController; there's our
Controller. Hook the controller's contentArray binding to the object
and name of the array you set up before. Now create the NSTableView,
and here's where it gets fun.
Set up the table view as usual, then go to each column and bind its
"value" binding to the controller, with the controller key
"arrangedObjects". The model key path should be the name of the
accessor for the value of that column. For example, if each row
contains a name, and the Model object has a "- (NSString *)name"
accessor, you would enter "name". Don't worry about all those settings
for the moment.
Provide a method in your Model object "- (void)setFromRow:(postgresql
row data type)rowData;" and have it set the internal object data from
the row _without using the modifiers_. Whenever postgresql notifies you
of a change, add and remove objects from the array as appropriate.
Then, while modifying existing objects, use the -setFromRow: method
instead of any of the modifiers. Finally, for each object that changed,
call [modelObjectInstance willChangeValueForKey:@"key name"] and
[modelObjectInstance didChangeValueForKey:@"key name"] for all the
pieces of data. The reasoning: the modifiers call sql to do an UPDATE,
so using them when receiving an update notification would send you into
an infinite loop; you have to notify the observers of the model object
by hand.
If this wickedly twisted bit of insanity is set up correctly, and I
haven't missed something important somewhere, it will do what you want
:). The Cocoa documents on Key-Value Coding, Key-Value Observing, and
Cocoa Bindings are HIGHLY recommended reading before attempting any of
this; they can be found at:
<
http://developer.apple.com/documentation/Cocoa/Conceptual/
KeyValueObserving/index.html>
<
http://developer.apple.com/documentation/Cocoa/Conceptual/
KeyValueCoding/index.html>
<
http://developer.apple.com/documentation/Cocoa/Conceptual/
CocoaBindings/index.html>
As a further disclaimer, I reiterate that I'm something of a newcomer
to bindings myself; I only risk this email because I believe I got the
concepts down quickly :).
-- Gwynne, key to the Code that runs us all
Formerly known as Sailor Quasar.
Email: email@hidden
Web:
http://musicimage.plasticchicken.com/
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.