Как мне просто перенаправить на другой приморский компонент верхнего уровня?

#components #smalltalk #pharo #seaside

#Компоненты #smalltalk #pharo #приморский

Вопрос:

Вопрос новичка. Google вообще не помог. Кроме того, проблему, с которой я столкнулся, довольно сложно правильно объяснить.

В моем приложении есть два компонента: JournalView и JournalEntryView. JournalView отображает список записей журнала со ссылками на отдельные записи. При нажатии каждая из этих ссылок должна создавать новый JournalEntryView и перенаправлять на этот вновь созданный JournalEntryView.

В настоящее время я делаю это:

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

Проблема в том, что этот код ожидает, что вновь созданный компонент ответит значением позже. Глядя на ореолы, я вижу следующую иерархию компонентов:

 JournalView
    WADelegation
        WAAnswerHandler
            JournalEntryView
 

Я этого не хочу. Я хочу, чтобы мой JournalEntryView был представлением верхнего уровня, и я просто хочу, чтобы мои якоря перенаправлялись на новый JournalEntryView верхнего уровня.

Возможно ли это в Seaside?

Ответ №1:

Вы можете использовать объявления. Это должно быть что-то вроде этого:

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

затем, когда вы объявляете ComponentA. Вы делаете что-то вроде этого:

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

Таким образом, вы объявляете своему родителю, что что-то произошло, и ваш родитель может отреагировать.

Этот подход работает большую часть времени, но вам нужно добавить механизмы в компоненты, чтобы реагировать на объявления (по умолчанию они не готовы). Если вы можете, лучший подход — создать свой собственный класс компонентов в верхней части вашей иерархии, который может обрабатывать объявления. Есть несколько примеров (в Pharo)…

Надеюсь, это поможет 🙂

Ответ №2:

Вы можете заменить корневой компонент, вызвав средство доступа #rootPresenter: в вашем сеансе. Это не то, что вы обычно делаете, но это возможно.

 self requestContext rootPresenter: aComponent
 

Ответ №3:

Хм, действительно странный вопрос. Не забывайте, что Seaside является фреймворком веб-приложения и не предназначен для отображения разных статических страниц. Также основной идеей Seaside является концепция продолжения, то есть что-то вроде потока или цепочки. Таким образом, у вас есть только одна точка входа в ваше веб-приложение. И чтобы легко управлять потоком, рекомендуется использовать task controller. Смотрите WATask и читайте здесь .

И, кстати, его очень плохой стиль для вызова из renderContentOn: .

Комментарии:

1. Итак, как бы вы порекомендовали это сделать? В этом случае мне не нужен расширенный поток управления, предлагаемый Seaside. Должен ли я просто сдаться и использовать call, чтобы заставить JournalEntryView отображать запись?

2. Он не #вызывал из #renderContentOn: (вы даже этого не можете сделать), он сделал это из обратного вызова, и это нормально.