How do I simply redirect to another toplevel Seaside component?

725 Views Asked by At

Newbie question. Google has been no help at all. Besides, the problem I have is kinda hard to explain properly.

I have two components in my application: a JournalView and a JournalEntryView. The JournalView displays a list of journal entries with links to individual entries. When clicked, each of these links should create a new JournalEntryView and redirect to this newly created JournalEntryView.

Currently, I do this:

html anchor
    callback: [
        entryView := JournalEntryView new.
        entryView entry: anEntry.
        self call: entryView ];
    with: '(read more)' ]

Problem is, this code expects the newly created component to answer with a value later. Looking at the halos, I can see the following hierarchy of components:

JournalView
    WADelegation
        WAAnswerHandler
            JournalEntryView

I don't want this. I want my JournalEntryView to be a toplevel view and I just want my anchors to redirect to a new toplevel JournalEntryView.

Is this possible in Seaside?

3

There are 3 best solutions below

0
On

You can replace the root component by calling the accessor #rootPresenter: in your session. Not something you would typically do, but it is possible.

self requestContext rootPresenter: aComponent
2
On

Hm, really strange question. Dont forget that Seaside is a web-application framework and not provided to show different static pages. Also the main idea of Seaside is continuation concept, i.e. something like flow or chain. Therefore, you have only one entry point of your web-application. And to easily control flow its recomend to use task controller. See WATask and read here.

And, by the way, its very bad style to call from renderContentOn:.

0
On

You can use announcements. It should be something like this:

ComponentA>>renderContentOn: html 
    html anchor
        callback: [
            self announce: (ViewEntryAnnouncement with: anEntry) ];
        with: '(read more)' ].

then, when you declare ComponentA. You do something like this:

ParentComponent>>initialize
    super initialize.
    componentA := (ComponentA new 
        on: ViewEntryAnnouncement do: [ :ann | 
            | entryView |
            entryView := JournalEntryView new.
            entryView entry: ann entry.                 
            self call: entryView ];
        yourself)

This way you are announcing your parent something has happened and your parent can react.

This approach works most of the time, but you need to add machinery to components to react to announcements (there are not ready by default). If you can, better approach is to create your own Component class, in top of your hierarchy, who can handle announcements. There are some of examples around (in Pharo)...

Hope this helps :)