[Seaside] Does this work for you? (WAS: Broken Seaside on SqueakMap)

Avi Bryant avi at beta4.com
Sat Jul 5 22:35:55 CEST 2003


On Sat, 5 Jul 2003, Nevin Pratt wrote:

> And aside from efficiency reasons, I don't see anything wrong with the
> example code, other than it simply doesn't work (and for no apparant or
> obvious reason).  Can anybody shed any light on why it doesn't work?

Yup.

Derek's exactly right about what the root of the problem is - that you're
recreating the subcomponent.  But let me try to explain *why* that is the
problem.

The way the delegation system works is this: if component X makes a #call:
to component Y, component Y gets stored as the delegate of X for the
duration of the call.  This means that if anyone asks X to render itself,
X will forward to Y so that Y gets rendered instead (or, if Y has made a
call, Y's delegate, and so on).

But in this system, the only component that knows about Y is X.  The only
way you will ever see Y is by asking X to render itself.

Since you're recreating the subcomponent every time, you're not keeping X
around, and so you'll never see Y.  That is, this is what's happening:

RESPONSE 1
create X
X delegate is nil
render X
X gets shown

REQUEST 1
X calls Y
X delegate is now Y

RESPONSE 2
create X'
X' delegate is nil
render X'
X' gets shown

Now, what you're intuitively expecting is for X' to somehow know that it's
occupying the same "place" that X did, and that since X is delegated to Y,
X' should render Y instead of itself.  I can understand where that
intuition is coming from, but how would the system actually *know* that?
There is no possible link between X' and X (and thus between X' and Y) -
they are both completely independent objects, stored in temps in different
invocations of what happens to be the same CompiledMethod.

In general, it doesn't make sense to recreate new components each time.
The whole point of a component is that it represents persistent UI state -
if you're going to throw it away on every render, it doesn't buy you
anything (and as you've found, can just confuse things).  You can use any
old class that implements #renderOn: for that (I usually call those
"Views", although there isn't a formal notion of View in Seaside, at least
not yet).

If you want a persistent notion of place, create some kind of container
component that represents that place.  It can hold very changeable
subcomponents (or, better, subviews) that get recreated every time - but
if you want to swap out that "place", send #inform: to the container, not
to the transient view.

Does all of that make sense?

Avi



More information about the Seaside mailing list