[Seaside] Finished the second tutorial

Avi Bryant avi@beta4.com
Tue, 23 Apr 2002 15:55:40 -0700 (PDT)


On Tue, 23 Apr 2002, Randy Siler wrote:

> Looking forward to more...

Yeah, there really oughta be a third tutorial by now (explaining
subcomponents through a simple calendar/todo-list).  I might have time for
that this weekend...

In the meantime, a brief primer on subcomponents:

- Any Seaside component can be embedded into the template of any other.
The easiest way to do this is by inserting a tag with the name of the
subcomponent and a dynamic id; for example, to embed the 'counter' example
into your page, add <IACounter sea:id="counter"></IACounter>.

- callPage: and jumpToPage: from within a subcomponent will replace that
subcomponent within the context of the parent page.  Thus, you can embed
entire applications and they'll (mostly) still work; this also allows
frame-like behavior without using frames.

- You can bind to the instance variables of a subcomponent.  These will be
synchronized with their bindings each time the component is viewed.  For
instance, in the above example of embedding IACounter, if you added the
following binding:

addBindingsTo: template
  (template elementNamed: 'counter')
    set: #count to: 42

Then the counter will stay fixed at 42.  These bindings can also be
bidirectional; if you have an instance variable called 'x' in your parent
component, and you have

addBindingsTo: template
  (template elementNamed: 'counter')
    bind: #count toPath: 'x'

then the 'x' instvar in the parent will be kept in sync with the counter
in the child.  Be careful about when you use set:... and when you use
bind:..., as you don't always want the subcomponent to be trying to push
its values back to the parent.

- Subcomponents can have default bindings.  Implement the #defaultBindings
method with a series of self bind:... statements.  You can use the 'id'
instvar to get the sea:id used in the template (in the above example, 'id'
would be set to 'counter').  A typical #defaultBindings looks like

defaultBindings
  self bind: #count toPath: id

- Subcomponents can access their parent through the instvar 'parent', and
the top-level component through 'self root'.  There is a special instvar
named 'container' that can be used to invoke methods on an unknown parent;
messages sent to container will be forwarded to the first parent found
that responds to them.  This is useful for subcomponents that know they'll
be used within a certain rough context, but don't want to be tightly
coupled to a specific parent.

- Some useful subcomponents that come with Seaside include IADateSelector,
IABatch, and IAPath.  There are a number more in the Seaside-Components
category, most of which have examples that illustrate their use in
Seaside-Examples.  Seaside-Examples-Store is also good for understanding
the use of subcomponents.  The pattern it uses of a simple "frame"
component at the toplevel, with the subcomponents doing most of the work,
is one I've found particularly useful.