[Seaside] Design (was Re: [Seaside] Web Calendar for Seaside)

Avi Bryant seaside@lists.squeakfoundation.org
Sun, 24 Nov 2002 11:23:52 -0800 (PST)


On Sun, 24 Nov 2002, Adrian Lienhard wrote:

> More tutorials: This would be really good: Helping beginners to have a
> smooth start and providing the advanced developers with helpful experience
> (e.g.  "patterns" for common problems).

Yes, I know.  Just a matter of having the time.  I'm hoping email
discussions like this will lead to some good material for them... or at
any rate help fill in the gaps.

> Domainmodel:
> How do you best access the domainmodel. Important seems to me to have the
> model separated from presentation as much as possible. To access the model I
> use the Session as following: It has a Classvar DomainModel and implements:
> MySession>>domainmodel which returns the unique instance. So in the Seaside
> code I use: "session domainmodel ...".

Sounds good.  I'm used to a database model where each session has an
instvar with its own data connection/cache, but if it's feasible for you
to have one global copy of the data this sounds like a good approach.

> Now there is the question of let each Component access the model like that
> or just let the root Component wich passes parts of the model to the child
> Components. For example:
>
> MyCompoundViewComponent>>initlialize
> tasklistview := MyTaskListView new
>       tasks: session domainmodel tasks.

Note that it's best to register the parent component with the child, so

  tasklistview := MyTaskListView new
                    parent: self;
                    tasks: session domainmodel tasks.

And yes, this seems like a decent way of doing things, in that it leaves
open the possibility of passing the TaskList some different list of tasks
(after filtered by a search, maybe?) in the future.

Note that "View" and "Component" have distinct meanings in my mind -
Components are descendents from WAComponent and maintain the UI state,
Views are descended from anything (maybe WAView) and are throwaway
presentation objects.  Having something called a ViewComponent is
confusing.

> and then
> MyCompoundViewComponent>>renderOn: html
> ...
> tasklistview renderOn: html.

Just a quick note - this is the same as
  html render: tasklistview
which I usually find easier to read.

> This leads to the second issue:
> In the "CompoundView"-Component - a Component wich puts several others (like
> Menu, Main-View etc.) together - I use instance vars to store the sub
> components. This makes them having state (e.g. for storing if a toolbar is
> open or closed etc.).

Right, good.

> But now, I'd like to call other Compponents from the sub components but just
> substituting the calling and not all. This means for example that "self
> call: CreateNewTask new" should show a page *with* the menu... How could
> this be done without much trouble?

Subcomponents that need to replace themselves (and not their parent) when
they do a "self call:..." need to be wrapped in a WAContainer.  The
simplest way to do this is when you create them in the parent, instead of
having

  toolbar := MyToolbarClass new parent: self.

write

  toolbar := self containerFor: MyToolbarClass new.

(setting the parent happens automatically when you do that, btw).

The container puts a level of indirection between the parent and the
child, allowing the child to swap itself out.  Note that your 'toolbar'
instvar is now an instance of WAContainer - to access the child component
itself, you need to write "toolbar contents", but note that if the child
is in the middle of the call, this could return some other component
instead...

> Avi (or other interested), if you have some minutes left to look at the code
> (it's not much yet), it would really be cool.

Feel free to send it and I'll take a look when I can.

Avi