 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Shawn Oster Guest
|
Posted: Tue Dec 09, 2003 9:44 pm Post subject: Help with data-aware objects in Model and State |
|
|
I'm pulling my hair out, anyone care to help prevent further hair loss?
I have what I *think* is a fairly solid data-aware framework. It allows
registering of heterogeneous data sources (not TDataSources) to a central
data broker (TMyDataBroker). My model requires data from all types of
sources, a database, from the model itself, from the environment, etc.
Every data-aware object has a link to a TDataField which knows how to get
the needed data, regardless of type. So far so good, works like a charm and
is fast.
Now the big hiccup. I need two different views of this data. I need the
live view (which basically pulls it's data from the database) and a sample
or design view. The first idea that comes to mind is to simply add a
property to the TMyDataBroker, something like UseSampleData: boolean. The
problem is that my data-aware objects are only linked to the TDataField,
which is contained in a TDataFieldList, which is owned by a TDataProvider,
which is contained in a TDataProviderList, which is finally owned by the
TMyDataBroker. The TDataField would have to follow an Owner chain 4 levels
up to find out if it should return real data or sample data.
Any thoughts on how to determine what the current state is inside my model
so I know what data to retrieve? I've asked a similar question like this
before about drawing routines and the suggestion was to have two different
views, so in this case a TLiveDataBroker and a TSampleDataBroker. That
worked wonderfully for drawing (thanks everyone) but that doesn't work in
this case because each object has a link to a TDataField. The model is
linked directly to the data.
My design below...
// base class for a single data field. I have a few descendant classes that
// work with concrete types, such as a DateTime, another that triggers
// an event when GetValue is called
TDataField = class
protected
procedure GetName(): string; virtual;
procedure GetValue(): string; virtual;
public
property Name: string read GetName();
property Value: string read GetValue();
end;
// type-safe TObjectList that holds TDataFields
TDataFieldList = class;
// holds a category of TDataFields. One of the categories is 'SystemInfo'
// with the fields being 'DefaultPrinter', 'MachineName'. Another is
'ModelInfo'
// with such fields as 'DocumentTitle', etc. Yet another is
'DatabaseProvider' which
// has a connection to a TDataSet. For each TField in the TDataSet there is
a mirrored
// TDataField in the provider.
TDataProvider = class;
public
DataFieldList: TDataFieldList;
end;
// type-safe TObjectList that holds TDataProviders
TDataProviderList = class;
// holds all the TDataProviders. Each TDataProvider is registered with the
broker with
// a category name. This way I can display all the categories (almost like
different tables)
// and their contained TDataFields for selection.
TDataBroker = class;
public
DataProviderList: TDataProviderList;
end;
// Holds a reference to a TDataField. Acts as a link between a data-bound
object
// and a TDataField, vary similar to a TFieldDataLink in DBCtrls. Also used
to pull
// just a subset of the TDataField's data. Some data-bound objects only
want the
// first character, or the last 3, etc.
TDataReference = class;
public
DataField: TDataField;
Length: integer;
StartPos: integer;
function GetValue(): string;
end;
// any data bound object
TSomeObject = class
public
DataReference: TDataReference;
end;
Thanks!
Shawn Oster
|
|
| Back to top |
|
 |
Eric Hill Guest
|
Posted: Tue Dec 09, 2003 11:04 pm Post subject: Re: Help with data-aware objects in Model and State |
|
|
| Quote: | Now the big hiccup. I need two different views of this data. I need the
live view (which basically pulls it's data from the database) and a
sample |
Can you just use a "development" database (DBISAM/Nexus/etc) that provides
a TDataset collection for use by the model at design time?
Eric
|
|
| Back to top |
|
 |
Marc Rohloff Guest
|
Posted: Wed Dec 10, 2003 3:01 pm Post subject: Re: Help with data-aware objects in Model and State |
|
|
Shawn Oster wrote on Tue, 9 Dec 2003 14:44:45 -0700 ...
<3fd64249 (AT) newsgroups (DOT) borland.com>
| Quote: | Now the big hiccup. I need two different views of this data. I need the
live view (which basically pulls it's data from the database) and a sample
or design view. The first idea that comes to mind is to simply add a
property to the TMyDataBroker, something like UseSampleData: boolean. The
problem is that my data-aware objects are only linked to the TDataField,
which is contained in a TDataFieldList, which is owned by a TDataProvider,
which is contained in a TDataProviderList, which is finally owned by the
TMyDataBroker. The TDataField would have to follow an Owner chain 4 levels
up to find out if it should return real data or sample data.
|
I don;t think that the UI should be aware (at least not at this level)
that it is in design view. Ideally you would just want the change to
occur at the dataprovider level (or maybe use different data providers
for design mode.
If you need to bubble information up to the field you should remeber
that it is always bad practice to use too many references (ie.dots) to
access information as it implies bad encapsulation.
ie: ThisField.FieldList.Provider.ProviderList.Broker.IsDesignMode
is bad.
TField should have a design mode property as should at least TProvider
and TBroker. This reduces the code to:
ThisField.IsDesignMode
Once you have encapsulated this way you can implement this anyway you
want. Initially you might choose to implement TField.IsDesignMode to
just return FieldList.provider.IsDesignMode which in turn returns
ProviderList.Broker.IsDesignMode.
If you later find that this is a performance bottle-neck you have
insulated yourself from the implementation. You can always change
Provider.IsDesignMode to return a private value and
DataBroker.IsDesignMode to notify all its providers that the design mode
has changed (which in turn can notify all its fields)
Marc Rohloff
marc rohloff at bigfoot dot com
|
|
| Back to top |
|
 |
Shawn Oster Guest
|
Posted: Fri Dec 12, 2003 10:42 pm Post subject: Re: Help with data-aware objects in Model and State |
|
|
"Marc Rohloff" <dont (AT) mailme (DOT) com> wrote
| Quote: | Shawn Oster wrote on Tue, 9 Dec 2003 14:44:45 -0700 ...
[email]3fd64249 (AT) newsgroups (DOT) borland.com[/email]
Now the big hiccup. I need two different views of this data. I need
the
live view (which basically pulls it's data from the database) and a
sample
or design view. The first idea that comes to mind is to simply add a
property to the TMyDataBroker, something like UseSampleData: boolean.
The
problem is that my data-aware objects are only linked to the TDataField,
which is contained in a TDataFieldList, which is owned by a
TDataProvider,
which is contained in a TDataProviderList, which is finally owned by the
TMyDataBroker. The TDataField would have to follow an Owner chain 4
levels
up to find out if it should return real data or sample data.
I don;t think that the UI should be aware (at least not at this level)
that it is in design view. Ideally you would just want the change to
occur at the dataprovider level (or maybe use different data providers
for design mode.
|
I've gone ahead and done something similar to this. I just didn't like
dealing with wiring up all the Owner properties. I see the VCL doing that
quite a bit, an object 3or 4 levels down (up?) knowing about the root object
of the model. It bothers me but I can see they probably had a reason.
I now have a data provider source which I swap out. So my
TDatabaseDataProvider links to a generic TDataSet, in design time I use a
kbmMemTable (thanks for the suggestion Eric Hill!) and when I go live I swap
that out for the "real" data. The only thing I don't like is that there is
some internal mapping from database field names to the field names in my
TDatabaseDataProvider that I need to rewire each time I set the source but
that seems a much better resolution.
Thanks for the help.
Shawn
|
|
| Back to top |
|
 |
Marc Rohloff Guest
|
Posted: Mon Dec 15, 2003 12:49 pm Post subject: Re: Help with data-aware objects in Model and State |
|
|
Shawn Oster wrote on Fri, 12 Dec 2003 15:42:43 -0700 ...
| Quote: | I now have a data provider source which I swap out. So my
TDatabaseDataProvider links to a generic TDataSet, in design time I use a
kbmMemTable (thanks for the suggestion Eric Hill!) and when I go live I swap
that out for the "real" data. The only thing I don't like is that there is
some internal mapping from database field names to the field names in my
TDatabaseDataProvider that I need to rewire each time I set the source but
that seems a much better resolution.
|
Yes. It's hard to get around the rewiring part. I suppose it wouldn't be
too hard to write a routine to go through all the controls on a form and
do it.
The Delphi Database way of doing it of course is not to link to a field
but to link to a database andf a string field name. THis has it's
advantages since you can repoint the datasource quite simply but I never
liked the fact that you wouldn't find out about bad field names until
runtime.
Marc
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|