[Seaside] [ENH] HandyComponent

Avi Bryant avi at beta4.com
Wed Mar 24 19:56:05 CET 2004


On Mar 24, 2004, at 9:04 AM, miso.list at auf.net wrote:

> Adds a few simple and handy utilities to your components:
>
> * a 'finite state machine': Seaside components are mostly restricted
> to rendering one page (#renderContentsOn:). This is often suboptimal
> design-wise, where one component (eg. PersonEditor) would ideally have
> all responsability for its area (eg. #displayPerson, #editPerson,
> #changePassword, etc.). HandyComponent allows you to do that by
> specifying what 'state' the component is in via e.g. 'self state:
> #editPerson'. On the next rendering cycle, this will automatically
> call the #editPerson method in your component (see #renderContentOn:).
> A link to 'edit' the person would thus be:
>   self anchorWithAction: [self state: #editPerson] text: 'edit'.
> The nil state triggers #proposeMainMenu, which does nothing by default
> This is the primary place that your subclass should override to fit
> your needs.

Can you give me a complete example of where you would use this?  It 
seems like the sort of thing that I would do with several components 
and a Task, and it would be interesting to compare the two 
implementation strategies.  Offhand, I don't see a great advantage to 
having multiple views provided by one class, but I'm open to being 
convinced.

> * a cache for the html canvas. This allows your rendering methods to
> be of the type #displayPerson, #editPerson rather than
> #displayPersonOn:, #editPersonOn:, etc. A small matter of taste, but I
> found it surprisingly more readable!

Yeah... I go back and forth on this one all the time.  As a practical 
matter, it's definitely nicer not to have to pass the renderer around 
all the time.  On the other hand, it just seems Wrong to use an inst 
var for such a transient purpose (there are no actual problems with it 
because Seaside is single threaded within a session, but it just tells 
the wrong story for me).  Best, if Smalltalk had them, might be a 
dynamically scoped variable, but I haven't seen any implementations of 
dynamic scope that I like yet.  What do other people think about this?

> * a simple error handling mechanism for form processing: while
> validating the form arguments, simply note each error by calling
> #userError: . This adds the error to a list of errors. At the end of
> validation, say 'self errors ifNotEmpty: [^self]. On the next
> rendering cycle, the errors will be automatically shown to the user,
> together with an explanation that the back button should be used to go
> back to editing.

I often do something similar, except that I display the errors at the 
top of the form instead of asking the user to backtrack.  If you're 
going to show the errors on a separate page, why not #call: a 
ValidationErrorList component instead of sticking it all in the same 
class?

Avi



More information about the Seaside mailing list