[Seaside] Re: Menu component - communicating with root component
Boris Popov
boris at deepcovelabs.com
Sun Apr 20 19:43:04 UTC 2008
I'm not convinced that adding a third-party negotiator is easier than,
Menu>>addItem: item
self items add: item.
item when: Clicked do: [self select: item].
MenuItem>>renderContentOn: html
html anchor
callback: [self announce: Clicked];
with: self label.
-Boris
-----Original Message-----
From: seaside-bounces at lists.squeakfoundation.org
[mailto:seaside-bounces at lists.squeakfoundation.org] On Behalf Of Holger
Kleinsorgen
Sent: Sunday, April 20, 2008 12:10 PM
To: Seaside - general discussion
Subject: Re: [Seaside] Re: Menu component - communicating with root
component
>> So... where is this announcer, how does bodyB obtain its
>> announcer? If there is one global announcer, then what routes
>> a ReloadBody to the Correct BodyA or B.
>
> OK, consider this, in Seaside, all components answer #children, so all
> parents have access to their children. The ChangeBody announcement
could be
> fired like this...
> self session announce: (ChangeBody sender: self with: [:body | body
call:
> BlaBla new])
> Now, both parent components catch the event, check to make sure the
#sender
> is one of their children or grandchildren with a quick recursive check
on
> #children, before deciding to process the announcement. This way you
scope
> the ChangeBody to the correct parent.
Peeking at grandchildren is IMHO even worse than accessing a parent.
It's the same princicple (traversing the component hierarchy), just more
laborious.
>> So menuItemB, performs "self announce: (anAnnouncement)" on
>> an announcer.
>>
>> ok... where is this announcer? How does it know about it?
>
> Put it on the session and then every component has access to a single
global
> announcer.
Using the session as global variable dump and central router for
application logic isn't very auspicious, too.
I faced a similiar problem recently, and initially used the
give-components-its-parent-but-only-use-it-for-announcing-approach.
however, it was doomed once I had to announce events between siblings.
Subscribing each and every component with potentially a lot of other
components didn't look very promising, too.
For instance, in VisualWorks, window events are sometimes dispatched in
both directions. First down, then up, with multiple interested parties
in the middle. It's hard to follow, and often fails as soon as the
hierarchy differs from the expected structure.
I finally ended up using an "environment" object, that holds some shared
data (selection etc.) and also acts as an announcer. Parent components
create it and pass it to their children. Children, when creating
grand-children, may decide to either pass the environment object to them
or create a new one.
In the example, there would be two such objects (one for A, one for B).
Let's call them EnvironmentA and EnvironmentB.
ParentA is subscribed to EnvironmentA. And for the menu flashing, MenuA
is subscribed to EnvironmentA, too (however, MenuA doesnt exactly know
that it is the EnvironmentA, for MenuA it's just "an Environment").
page reload goes like this:
MenuItem>>triggerReload
self environment announce: (Reload page: ...)
menu flashing
MenuItem>>flash
self envronment announce: (Flash ...)
and to make it work:
Menu>>initialize
self environment when: Flash do: [ : gordon | self flash: gordon ]
Parent>>initialize
self environment when: Reload do: [ : page | self call: page ].
the advantage of this approach is, that it won't break when you leave
the strictly hierarchical approach. And you don't need a central router.
And you don't break encapsulation rules.
_______________________________________________
seaside mailing list
seaside at lists.squeakfoundation.org
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
More information about the seaside
mailing list