Когда использовать компоненты Seaside, а когда использовать простые объекты рендеринга? - PullRequest
17 голосов
/ 08 мая 2009

Недавно я разрабатывал веб-приложение в Seaside + Squeak и обнаружил, что это замечательный опыт. Seaside действительно на голову выше всех остальных фреймворков, и мне кажется, что я работаю на более высоком уровне абстракции (выше цикла запросов / ответов HTTP и HTML-шаблонов, с которыми вам приходится иметь дело в других фреймворках).

Тем не менее, я немного запутался в компонентах Seaside. Недавно мне пришлось отобразить список объектов на компоненте (аналогично главной странице stackoverflow). Сначала я сделал каждый объект компонентом (подкласс WAComponent), но это оказалось очень расточительным, и мне пришлось динамически устанавливать #children в родительском компоненте, чтобы он вообще работал. Затем я попытался заставить их отображать объекты (объекты, которые не являются подклассами WAComponent, и визуализировать с использованием renderOn: вместо renderContentOn: как это делают компоненты). Это работало, но теперь они больше не могли обращаться к глобальному состоянию в объекте сеанса, как это могут компоненты (используя #session). Затем я обнаружил «значение WACurrentSession», которое дает любому объекту доступ к текущему объекту сеанса Seaside. Теперь я мог заставить их отображать объекты. Кроме того, я обнаружил, что я могу переписать многие другие, более мелкие компоненты в качестве объектов рендеринга.

Помимо необходимости вызова / ответа или состояния возврата, какие еще есть причины для использования компонентов над объектами рендеринга?

1 Ответ

16 голосов
/ 08 мая 2009

Это частая путаница для новых пользователей Seaside. Мы изо всех сил старались сделать это более понятным в Seaside 2.9, который в настоящее время находится в Alpha, но я постараюсь сосредоточиться на 2.8 здесь, так как похоже, что это то, что вы используете.

Прежде всего, вы правы, что вам не нужно использовать Компонент для доступа к Сессии. Seaside 2.9 перемещается #session в новый класс WAObject, который делает его доступным почти для всех объектов Seaside (включая Компоненты), но вы определенно можете ссылаться на WACurrentSession на данный момент в 2.8.

Компоненты обеспечивают примерно следующую функциональность в 2.8:

  1. #renderContentOn: вызывается с экземпляром любого класса рендерера, который вы указываете в #rendererClass (вместо того, чтобы использовать тот рендерер, который используется, когда ваш объект просят визуализировать себя)
  2. Хук (#updateUrl:), позволяющий обновить URL-адрес, используемый средством визуализации для создания ссылок
  3. Хуки (#updateRoot:, #style, #script) для обновления раздела HEAD HTML-документа
  4. Возможность быть корнем приложения
  5. Крючки (#updateStates:, #states) для облегчения возврата состояния
  6. Хук (#initialRequest:), чтобы разрешить инициализацию на основе запроса, вызвавшего создание сеанса
  7. Средство (#children), позволяющее удостовериться, что все компоненты, расположенные ниже вас, также будут вызывать вышеуказанные крючки
  8. Возможность добавления украшений
  9. Возможность показать / ответить / позвонить (использует украшения)
  10. Некоторые удобные методы (#inform:, #isolate: и т. Д.)

Если вам не нужно ничего из вышеперечисленного, вам не нужен компонент. Если вам нужно что-то из вышеперечисленного, вам в значительной степени нужен Компонент, если вы не хотите реализовать эквивалентную функциональность в своем собственном классе.

Возможно, простейшая метрика: если вы намерены хранить объект между HTTP-запросами, это должен быть Компонент; если вы намереваетесь выбрасывать объект и создавать его при каждом проходе рендеринга, это, вероятно, не обязательно. Если вы представляете приложение, которое отображало страницы блога, у вас, вероятно, были бы Компоненты для меню, рулона блога, тела блога, каждого комментария и так далее. Возможно, вы захотите выделить чтение разметки блога и генерацию его HTML, чтобы вы могли поддерживать разные разметки или разные средства визуализации и чтобы компоненты комментариев могли поддерживать одну и ту же разметку. Это можно сделать с помощью некомпонентного класса, который реализует #renderOn: и может быть создан и использован другими компонентами по мере необходимости.

Seaside 2.9 в настоящее время разделяет вышеуказанную функциональность, делая бетон WAPresenter и вводя WAPainter в качестве суперкласса. 1-3 выше реализованы на WAPainter и 4-7 на WAPresenter, поэтому у вас есть выбор того, что подкласс в зависимости от ваших потребностей. Он также удаляет множество методов из WAPresenter и WAComponent, чтобы облегчить их понимание конечными пользователями.

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

...