A few bits about children in Seaside
As I start to understand more about Seaside, I'll post notes here from time to time capturing my learning. Here's a few basic things I now know about how children work.
- The rendering process is a hierarchy of WAComponent-derived objects, one of which has been designated as the "root" in the configuration. (Additional render loops can be created for things like pop-ups.)
- Each component must answer its immediate children in the tree by overriding #children. (You can answer more children than may necessarily be chosen on this rendering in a dynamic child situation, but you must at least answer all of the children you might render.)
^ Array with: topnav with: leftnav with: body.
- Each component should render its immediate children somewhere in its own render method by calling #render: on the canvas. (If you don't override #renderContentOn:, you'll get a default behavior that will do this anyway without any extra embellishment.)
renderContentOn: html
...
html render: topnav.
...
html render: leftnav.
...
html render: body.
...
- A component can temporarily replace itself with a different component with #call:. This should not be done as part of the render, because that would be some sort of weird brundlefly experiment. Instead, it will always be as part of a callback:
renderContentOn: html
...
html anchor callback: [self call: self newbody]; with: 'go here'.
...
newbody
^[a different component component]
- When the anchor is selected, a new render (from the top) will be performed, with the component that called #call: temporarily replaced with the result of #newbody. It should have its own #renderContentOn:, #children, and so on. When the component returned by #newbody wants to pop the stack, it calls #answer or #answer: (from a callback!) and the original component will appear again.
- Use #call: only when you will be coming back. You can also just change the components instead, if it's unidirectional rather than call and return:
initialize
super initialize.
body := self body1. "set up the initial component"
children
^ Array with: body. "don't forget this!"
renderContentOn: html
...
html anchor callback: [body := self body1]; with: 'first body'.
html anchor callback: [body := self body2]; with: 'second body'.
...
html render: body. "render the current body"
...
- Now, picking one of the two links will select which "body" gets rendered. No #call: is needed, because we don't need to stack the states to return to it.
(First posted to the Seaside mailing list. Thanks to Ramon Leon, Sebastian Sastre, and Philippe Marschall for corrections.)