Открыть список
Как стать автором
Обновить

Zend Framework: стремимся к MVC для Javascript, CSS

Zend Framework
При постепенном изучении Zend Framework и построении с его помощью базовых приложений я заметил, что клиентский js-код и инлайновые стили попадают в скрипты вида, при этом они начинают занимать почти половину всего скрипта. В принципе, ничего плохого в этом нет, но мне такая мусорка начала давить на глаза. Кроме того, инлайновый js постепенно превращается в жестко привязанную к скрипту вида конструкцию, полностью зависимую как от самого скрипта, так и от переданных контроллером данных. При всем этом не оставляет желание писать на javascript код максимально красивый при помощи библиотеки jQuery.

Итак, что в данном случае можно сделать. Первая же мысль — вынести инлайновые скрипты и стили во внешние файлы и подключать их через помощники вида headLink и headStyle. Если со стилями все примерно понятно — достаточно специфический стиль для конкретного вида вынести в css файл и подключать его по мере необходимости, то js по-прежнему зависим от данных.

В качестве первого решения напишем плагин к frontController для подключения по мере необходимости нужных файлов:

  1. class My_Controller_Plugin_Webinit extends Zend_Controller_Plugin_Abstract
  2. {
  3. public function preDispatch()
  4. {
  5. $controllerName = $this->_request->getControllerName();
  6. $actionName = $this->_request->getActionName();
  7. $view = Zend_Layout::getMvcInstance()->getView();
  8. if ( file_exists(APPLICATION_CSS_FOLDER.'/'.
  9. $controllerName.'/'.
  10. $actionName.'.css') )
  11. {
  12. $view->assign('cssControllerAction',$controllerName.'/'.$actionName.'.css');
  13. }
  14. if ( file_exists(APPLICATION_JS_FOLDER.'/'.
  15. $controllerName.'/'.
  16. $actionName.'.js') )
  17. {
  18. $view->assign('jsControllerAction', $controllerName.'/'.$actionName.'.js');
  19. }
  20. }
  21. }
* This source code was highlighted with Source Code Highlighter.


Не забываем в Bootstrap классе подключить созданный плагин:

  1. protected function _initFrontControllerPlugins()
  2. {
  3. $frontController = Zend_Controller_Front::getInstance();
  4. $frontController->registerPlugin( new My_Controller_Plugin_Webinit() );
  5. }
* This source code was highlighted with Source Code Highlighter.


Как уже понятно, используемые css и js файлы размещаются в соответствии с полной аналогией размещения скриптов вида. Только вместо /application/views/script/controllerName/actionName/ корневыми директориями для них будет соответственно public/css/ и public/js/. Для этого нужно объявить три константы в index.php:

  1. defined('APPLICATION_PUBLIC_FOLDER')
  2. || define( 'APPLICATION_PUBLIC_FOLDER',
  3. dirname(__FILE__) );
  4. defined('APPLICATION_CSS_FOLDER')
  5. || define( 'APPLICATION_CSS_FOLDER',
  6. realpath(APPLICATION_PUBLIC_FOLDER . '/css') );
  7. defined('APPLICATION_JS_FOLDER')
  8. || define( 'APPLICATION_JS_FOLDER',
  9. realpath(APPLICATION_PUBLIC_FOLDER . '/js') );
* This source code was highlighted with Source Code Highlighter.


Плагин позволяет подключить в нашем Layout нужные файлы следующим кодом:

  1. <? if ($this->cssControllerAction) $this->headLink()->appendStylesheet('/css/'.$this->cssControllerAction)?>
  2. <? if ($this->jsControllerAction) $this->headScript()->appendFile('/js/'.$this->jsControllerAction)?>
* This source code was highlighted with Source Code Highlighter.

Открываем браузер — нужные файлы подключились.

Остается вопрос с жаваскриптом. Мы вынесли код во внешний файл в пределах public директории. Но есть необходимость, например, вывести приветственный текст на основе словаря функцией alert(). Естественно, для перевода используется Zend_Translate, но опять же, как быть, если все наши данные доступны только в скрипте вида?

Для собственных задач я посчитал идеальным решением организацию неймспейсов. К примеру, для переводчика внутри одного скрипта вида нам необходим ограниченный набор фраз. Значит мы можем организовать хранилище этих фраз и отдать их необходимому обработчику на уровне js.

Вот как это происходит.

В основном js-файле моего проекта application.js происходит настройка глобальных методов, объектов и обработчиков. Сюда можно добавить:

  1. $(document).ready(function(){
  2. $.TRANSLATION = {};
  3. });
* This source code was highlighted with Source Code Highlighter.


Хранилище огранизовано, теперь нужно заполнить его.

Для этого в скрипте вида нам понадобится следующий код:

  1. <script type="text/javascript">
  2. $(document).ready(function(){
  3. $.data($.TRANSLATION, "Nice to see you!", '<?=$this->translate("Nice to see you!")?>');
  4. </script>
* This source code was highlighted with Source Code Highlighter.


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

  1. alert( $.data($.TRANSLATION, "Nice to see you!") );
* This source code was highlighted with Source Code Highlighter.


Итак, мы получили следующую картину: для контроллера index, экшена index существует файл в паблик-директории /js/index/index.js, являющийся набором функций для работы. При этом все необходимые данные попадают в хранилище данных непосредственно в скрипте вида, а само хранилище объявляется глобально для всех скриптов вида в основном js-файле приложения.

По модели MVC. Немного притянуто за уши, но все же.

В качестве контроллера (реакцией на пользователя) выступает плагин к frontController, организующий подключение, скрипт layout-а и основа — application.js.

В качестве модели выступает скрипт вида, накапливающий данные для js хранилища.

В качестве вида выступает подключаемый код javascript, полностью отвечающий за клиентское представление.

В хранилище можно накапливать любые данные для дальнейшего использования.
Теги:zend frameworkphpjsjquerymvc
Хабы: Zend Framework
Всего голосов 11: ↑7 и ↓4 +3
Просмотры5.1K

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

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Похожие публикации

PHP-разработчик / Backend Developer
от 60 000 до 150 000 ₽MediaLineМоскваМожно удаленно
Разработчик frontend JS / jQuery / Vue.js
до 150 000 ₽Хостинг-технологииМожно удаленно
Backend PHP Developer
от 200 000 ₽GOSOBLAKOМожно удаленно
Разработчик фронтэнд (JS/jQuery/React/Vue)
от 80 000 до 130 000 ₽ИнфокультураМоскваМожно удаленно
PHP-разработчик
от 100 000 ₽Sellout DigitalКазань

Лучшие публикации за сутки