Создание динамических интерфейсов и  AJAX- приложений  промышленного класса с помощью Dojo Toolkit  и  Zend Framework Георгий   Туревич,  Wizartech
Немного о себе Ведущий веб-программист компании Wizartech Более 7-и лет использования PHP и JavaScript Более 2-х лет использования Zend Framework Около 1-го года активного использования Dojo Toolkit (с момента заключения партнерства с Zend   Framework) и создания индивидуальных компонентов Принимаю активное участие в развитии сообщества  ZendFramework . ru  (с момента создания) Модератор русскоязычной группы рассылки «RU  DojoToolkit  JS Framework» на  Google Groups
Промышленный? Богатый функционал Гибкая архитектура Проверенный код Код библиотек покрыт тестами Собственный инструментарий для тестирования Постоянное развитие и ясное будущее Поддержка от  Zend Technologies  и  Sitepen Мощное сообщество Zend Framework:  Adobe, Google, Sitepen, Microsoft, Nirvanix,   Strikiron Dojo Toolkit :  Sun, IBM, Google, AOL, Uxebu, Sitepen Лицензирование Zend Framework:  New BSD License Dojo Toolkit :  Modified BSD license \ The Academic Free License 2.1
Dojo Toolkit
Где взять  Dojo ? Скачайте напрямую Subversion   /   Git   /   Bazaar CDN (Google, AOL ,  …)
Архитектура  Dojo Toolkit
Вкратце о  Core  и  Base Полезные утилиты Обработка событий Ajax (Restful XHR, script, iframe)  Манипулирование узлами Интернационализация Перетаскивание Анимация Абстракция данных Имитация классов и наследования
Dojo Toolkit Core  и  Base
Инициализация <html> <head> <title> Dojo </title> <script type=&quot;text/javascript&quot; src=&quot;http://o.aolcdn.com/dojo/1.3/dojo.xd.js&quot;> </script> </head> <body> HELLO  PHPCONF 2009 !!! </body> </html> Также можно использовать: Другие  CDN  (помимо  AOL  и  Google  можно использовать собственные XD -сборки) Локальные копии  Dojo Toolkit
Конфигурирование <script type=&quot;text/javascript&quot; src=&quot;/dojotoolkit/dojo/dojo.js&quot; djConfig=&quot;isDebug:true,parseOnLoad:true&quot; > </script> Конфигурировать возможно прямо в тэге  <script> : Или программным способом (для соответствия стандартам): <script> var djConfig = {isDebug: true, parseOnLoad: true} </script> <script type=&quot;text/javascript&quot; src=&quot;/dojotoolkit/dojo/dojo.js&quot;> </script>
Система управления пакетами и зависимостями <script> dojo.require(&quot;dojo.fx&quot;); dojo.require(&quot;dojo.io.script&quot;); dojo.registerModulePath(&quot;wlib&quot;, &quot;/js/wlib/&quot;); dojo.require(&quot;wlib.Example&quot;);   // /js/wlib/Example.js var exampleObj = new wlib.Example(); </script>
Система управления пакетами и зависимостями dojo.provide(&quot;wlib.Example&quot;); dojo.declare(&quot;wlib.Example&quot;, null, { constructor: function() { console.log(&quot;HELLO! It is example!&quot;); } }); /js/wlib/Example.js Вывод в консоли  Firebug Lite ( упрощенный аналог плагина для  FF) :
dojo.addOnLoad() Интересное в Base и   Core События dojo.addOnUnload() <script> var onLoadFunc = function() {  console.log('Да! Страница загружена!'); } dojo.addOnLoad(onLoadFunc); </script> <script> var onUnloadFunc = function() { alert('Закрываем страницу'); } dojo.addOnUnload(onUnloadFunc); </script>
Интересное в Base и   Core События dojo.connect() <a href=&quot;http://phpconf.ru&quot; id=&quot;link&quot;>Все на конференцию</a> <script> dojo.connect(dojo.byId('link'),'onclick',   function(evt)   { dojo.stopEvent(evt); console.log('Вы щелкнули на ссылку!'); }); </script>
Интересное в Base и   Core События dojo.connect() / dojo.disconnect() <script> function foo() { console.log('Вызвана функция foo') } function bar() { console.log('Вызвана фукция bar')   } var conn = dojo.connect('foo', bar); foo(); console.log('--- Удаляем соединение --- '); dojo.disconnect(conn); foo(); </script>
Интересное в Base и   Core События dojo.connect() / dojo.disconnect()
Интересное в Base и   Core События dojo.subscribe(), dojo.unsubscribe(), dojo.publish() <script> function handlerFirst(data) { console.log(&quot;Функция handlerFirst, Данные:&quot;, data); } function handlerSecond(data) { console.log(&quot;Функция handlerSecond, Данные:&quot;, data); } var subscrFirst  = dojo.subscribe('mySubscribe', null, handlerFirst); var subscrSecond  = dojo.subscribe('mySubscribe', null, handlerSecond); </script>
Интересное в Base и   Core События dojo.subscribe(), dojo.unsubscribe(), dojo.publish() <script> dojo.publish(&quot;mySubscribe&quot;, [&quot;Привет всем!&quot;]); dojo.publish(&quot;mySubscribe&quot;, [&quot;Пока всем!&quot;]); console.log(&quot; --- Очищаем subscrFirst --- &quot;); dojo.unsubscribe(subscrFirst); dojo.publish(&quot;mySubscribe&quot;, [&quot;Привет всем!&quot;]); dojo.publish(&quot;mySubscribe&quot;, [&quot;Пока всем!&quot;]); </script>
Интересное в Base и   Core События dojo.subscribe(), dojo.unsubscribe(), dojo.publish()
Интересное в Base и   Core Ajax Полный  Restful  набор   функций: dojo.xhrGet() dojo.xhrPost() <script> dojo.xhrPost({ url: &quot;./test.php&quot;, handleAs: &quot;text&quot;, content: {a: &quot;1111&quot;, b: &quot;2222&quot;}, load: function(response, ioArgs) { console.log(response); return response; } }); </script> dojo.xhrPut() dojo.xhrDelete()
Интересное в Base и   Core Ajax test.php <?php print_r($_POST);
Интересное в Base и   Core Ajax dojo.Deffered   (позволяет создавать цепочки функций обратного вызова)   <script> function firstCallback(response, ioArgs) { console.log(&quot;Вызван firstCallback : &quot;, response); return response; } function secondCallback(response, ioArgs) { console.log(&quot;Вызван secondCallback : &quot;, response); return response; } </script>
Интересное в Base и   Core Ajax dojo.Deffered  <script> var deffered = dojo.xhrPost({ url: &quot;./test_deffered.php&quot;, handleAs: &quot;json&quot;, content: {a: &quot;1111&quot;, b: &quot;2222&quot;}, load: function(response, ioArgs) {} }); deffered.addCallback(firstCallback); deffered.addCallback(secondCallback); </script> Также есть возможность добавлять: Исключительно обработчики ошибок ( addErrback  метод) Универсальные обработчики ( addBoth  метод)
Интересное в Base и   Core Ajax test _ deffered.php <?php echo json_encode($_POST);
Имитация классов и наследования dojo.declare() <script> dojo.declare(&quot;wlib.ExampleParentFirst&quot;, null, { constructor: function() { console.log(&quot;Вызов конструктора&quot;); } }); dojo.declare(&quot;wlib.ExampleParentSecond&quot;, null, { say: function(message) { console.log(message) } }); </script>
Имитация классов и наследования dojo.declare() <script> dojo.declare( &quot;wlib.ExampleParentChild&quot;, [wlib.ExampleParentFirst, wlib.ExampleParentSecond], { sayBy: function() { this.say(&quot;Всем пока!&quot;) } } ); var child = new wlib.ExampleParentChild(); child.sayBy(); </script>
Имитация классов и наследования dojo.declare()
Имитация классов и наследования dojo.extend() <script> dojo.extend(wlib.ExampleParentChild, { sayHello: function() { this.say(&quot;Всем привет!&quot;); } }) ; var child = new wlib.ExampleParentChild(); child.sayHello(); child.sayBy(); </script>
Имитация классов и наследования dojo.mixin() <script> var obj = { firstName: &quot;Иван&quot;, lastName: &quot;Петров&quot; }; var emp = dojo.mixin(obj, { sayName: function() { console.log( &quot;Меня зовут &quot;   + this.firstName + &quot; &quot; + this.lastName ); } }); emp.sayName(); </script>
Имитация классов и наследования dojo.hitch() <script> function sayName() { console.log( &quot;Меня зовут &quot; + this.firstName + &quot; &quot; + this.lastName ); } var obj = { firstName: &quot;Иван&quot;, lastName: &quot;Петров&quot; }; var callback = dojo.hitch(obj, sayName); callback(); </script>
Dojo Toolkit Dijit
Что такое  Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм  (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.)
Элементы форм
Что такое  Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм  (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.) Виджеты компоновки   ( Content pane, Accordion   /   Tab   /   Stack   / Border - контейнеры )
Виджеты компоновки
Что такое  Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм  (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.) Виджеты компоновки   ( Content pane, Accordion   /   Tab   /   Stack   / Border - контейнеры ) Виджеты приложения  (деревья, прогресс-бар, диалоги, меню, WYSIWYG  и т . д.)
Виджеты приложения
Что такое  Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм  (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.) Виджеты компоновки   ( Content pane, Accordion   /   Tab   /   Stack   / Border - контейнеры ) Виджеты приложения  (деревья, прогресс-бар, диалоги, меню, WYSIWYG  и т . д.) Доступность  ( Accessibility (a11y)) Шаблонность (встроенный шаблонизатор) Готовые темы оформления (tundra, soria, nihilo, noir)
Инициализация виджетов <script src=&quot;/dojotoolkit/dojo/dojo.js&quot; djConfig=&quot;isDebug: true,  parseOnLoad: true &quot; ></script> <script> dojo.require(&quot; dijit.form.Button &quot;); </script> <link id=&quot;themeStyles&quot; rel=&quot;stylesheet&quot; href=&quot; /dojotoolkit/dijit/themes/tundra/tundra.css &quot;> В секции  <head> : Устанавливаем  parseOnLoad  в  true Подключаем нужные виджеты Подключаем тему оформления
Инициализация виджетов <div class=&quot;tundra&quot;> <button id=&quot;buttonHello&quot;></button> <button dojoType=&quot;dijit.form.Button&quot;> Щелкни по мне! </button> </div> <script> var button = new dijit.form.Button({ label: &quot;Привет!&quot;, name: &quot;programmatic&quot; }, &quot;buttonHello&quot;); </script> В секции  <body> :
Инициализация виджетов Одна кнопка инициализирована программным способом Вторая кнопка инициализирована декларативным способом
Возможности расширения Переопределение методов жизненного цикла constructor()  (конструктор) postMixInProperties()  (вызывается после формирования структуры виджета) buildRendering()  (генерирует визуальное отображение виджета) postCreate()  (вызывается сразу после создания визуального отображения) startup()  (вызывается после создания всех дочерних виджетов и самого виджета) Шаблон Можно встраивать в код класса Можно выносить в отдельный файл Языковые файлы Можно встраивать в код класса Можно выносить в отдельный файл
Dojo Toolkit Dojox
Dojox Dojox   —   собрание расширенных, дополнительных и экспериментальных компонентов (Extensions, Extras, Experiments) Состав: Расширения Dijit (dojox.widget, dojox.layout, dojox.form) Дополнительная анимация: dojox.fx (Morph, Text, Extras, ...) Виджеты изображений (FlickrBadge, Lightbox (Nano), SlideShow, ...) Расширенный IO (RPC, REST, SMD, ScriptFrame, ...) И многое другое …
Dojox Кроссбраузерная векторная графика: GFX API Charting GFX 2D   /   3D GFX -анимации
Dojox dojox.grid.Grid
Dojo Toolkit Данные
Абстракция  работы с данными Все типы хранилищ реализуют один или несколько интерфейсов: dojo.data.api.Read  (чтение, поиск, сортировка и фильтрация элементов данных) dojo.data.api.Write  (создание, удаление, обновление элементов данных) dojo.data.api.Identity  (доступ к элементам по средствам уникальных идентификаторов) dojo.data.api.Notification  (уведомление о таких событиях, как создание, удаление или обновление элементов данных)
Абстракция  работы с данными Dojo dojo.data.ItemFileReadStore dojo.data.ItemFileWriteStore Dojox AtomReadStore CouchDBRestStore CssRuleStore CsvStore FileStore FlickrRestStore/FlickrStore GoogleFeedStore GoogleSearchStore HtmlStore jsonRestStore QueryReadStore ServiceStore S3Store WikipediaStore XmlStore И другие …
Dojo Toolkit Util
Подготовка к выпуску в эксплуатацию В пакете  Dojo Toolkit  поставляется утилита  ShrinkSafe   (Java), которая реализует следующие функции: Уменьшение количества HTTP-запросов Объедение файлов с классами, шаблонами, языковыми данными Уменьшение размера JavaScript-файлов Удаление комментариев и пробелов Сокращение наименований переменных CSS-оптимизация Объединение @import-файлов в один Удаление комментариев Опции StripConsole X-Domain-сборки (свой CDN)
D.O.H Система модульного тестирования Поддерживает  assert*, buildUp, tearDown– методы, тестирование синхронных и асинхронных запросов, включает в себя подсистему тестирования визуальных компонентов  doh.robot .
Интеграция  Dojo Toolkit и  Zend Framework Программная настройка  Dojo -окружения Автоматизация работы с виджетами Генерация спец. форматов данных Упрощение выпуска в эксплуатацию
Zend Framework
Программная настройка  Dojo -окружения Типичный код в  <head>  секции для настройки  Dojo : <style type=&quot;text/css&quot;> @import &quot;/js/dojo-toolkit/dijit/themes/tundra/tundra.css&quot;; </style> <script type=&quot;text/javascript&quot;> var djConfig = {&quot;isDebug&quot;:true,&quot;parseOnLoad&quot;:true}; </script> <script type=&quot;text/javascript&quot;  src=&quot;/js/dojo-toolkit/dojo/dojo.js&quot;></script> <script type=&quot;text/javascript&quot;> dojo.require(&quot;dojo.io.script&quot;); dojo.require(&quot;dojo.fx&quot;); dojo.require(&quot;dijit.form.Button&quot;); </script>
Программная настройка  Dojo -окружения Конфигурация с помощью  dojo() view- хелпера: <?=$this->dojo() ->enable() ->setDjConfig( array('isDebug' => true, 'parseOnLoad' => true) ) ->setLocalPath('/js/dojo-toolkit/dojo/dojo.js') ->addStyleSheetModule('dijit.themes.tundra') ->requireModule( array('dojo.io.script', 'dojo.fx', 'dijit.form.Button') )?>
Программная настройка  Dojo -окружения Шаг в будущее   В активной разработке плагин бустрапа Zend_Application_Resource_Dojo,  с помощью которого: <?=$this->dojo() ?> И в  application.ini : resources.dojo.djConfig.isDebug = 1 resources.dojo.djConfig.parseOnLoad = 1 resources.dojo.localPath = &quot;/js/dojo-toolkit/dojo/dojo.js&quot; resources.dojo.requireModule[] = &quot;dojo.io.script&quot; resources.dojo.requireModule[] = &quot;dojo.fx&quot; resources.dojo.requireModule[] = &quot;dijit.form.Button&quot; В макете указываем:
Работа с виджетами View- хелперы В шаблоне: <h1>Форма</h1> <div class=&quot;tundra&quot;> <form> <?=$this->editor('editor')?> <?=$this->button( 'send', 'Отправить')?> </form> </div>
Работа с виджетами Элементы форм В контроллере: $form = new Zend_Dojo_Form(); $form->addElement('editor', 'editor'); $form->addElement( 'button', 'send', array('label' => 'Отправить') ); $this->view->form = $form; <h1>Форма</h1> <div class=&quot;tundra&quot;> <?=$this->form?> </div> В шаблоне:
Работа с виджетами Состав компонентов В состав элементов для  Zend_Dojo_Form  входят классы для большинства виджетов формы Так же реализованы  view- хелперы и декораторы для форм, которые упрощают работу с виджетами компоновки: AccordionContainer AccordionPane BorderContainer SplitContainer StackContainer TabContainer ContentPane
Ajax Zend_Dojo_Data Формируем форму: public function dojoDataExampleAction() { $form = new Zend_Dojo_Form(); $form->addElement( 'FilteringSelect', 'city', array( 'label' => 'City', 'storeId' => 'cityStore', 'storeType' => 'dojo.data.ItemFileReadStore', 'storeParams' => array( 'url' => '/json/simple-city-store/', ), 'dijitParams' => array( 'searchAttr' => 'name', ) ) ); $this->view->form = $form; }
Ajax Zend_Dojo_Data Отдаем данные в формате  dojo.data : public function simpleCityStoreAction() { $data = array( array('id' => 1, 'name' => 'Волгоград'), array('id' => 2, 'name' => 'Москва'), array('id' => 3, 'name' => 'Минск'), array('id' => 4, 'name' => 'Мурманск') ); $dojoData = new Zend_Dojo_Data('id', $data); echo $dojoData; }
Ajax Zend_Dojo_Data Отдаем данные в формате  dojo.data : { &quot;identifier&quot;:&quot;id&quot;, &quot;items&quot;:[ {&quot;id&quot;:1,&quot;name&quot;:&quot;Волгоград&quot;}, {&quot;id&quot;:2,&quot;name&quot;:&quot;Москва&quot;}, {&quot;id&quot;:3,&quot;name&quot;:&quot;Минск&quot;}, {&quot;id&quot;:4,&quot;name&quot;:&quot;Мурманск&quot;} ] }
Ajax Zend_Dojo_Data В шаблоне: <div class=&quot;tundra&quot;><?=$this->form?></div> Вуаля!
Ajax JSON-RPC Клиентская часть (в шаблоне): <? $this->dojo()->requireModule(&quot;dojo.rpc.JsonService&quot;); ?> <? $this->dojo()->onLoadCaptureStart(); ?> function() { var o = { &quot;serviceType&quot;: &quot;JSON-RPC&quot;, &quot;serviceUrl&quot;: &quot;/json/rpc-server&quot;, &quot;methods&quot;: [{ &quot;name&quot;: &quot;sum&quot;, &quot;parameters&quot;: [ {name: &quot;numbers&quot;} ] }] } ... } <? $this->dojo()->onLoadCaptureEnd(); ?>
Ajax JSON-RPC Клиентская часть (в шаблоне): ... var rpcObject = new dojo.rpc.JsonService(o) var sum = rpcObject.sum([4,8,15,16,23,42]); sum.addCallback(function(response) { console.log(&quot;Сумма чисел: &quot;, response) }); Запрос: {&quot;params&quot;:[[4,8,15,16,23,42]],&quot;method&quot;:&quot;sum&quot;,&quot;id&quot;:1}
Ajax JSON-RPC Серверная часть  ( модель): class Default_Model_RpcTest { function sum($numbers) { return array_sum($numbers); } }
Ajax JSON-RPC Серверная часть (контроллер): public function rpcServerAction() { $server = new Zend_Json_Server(); $server->setClass('Default_Model_RpcTest'); $server->handle(); } Результат:
Ajax Rest Dojo Toolkit Хранилища dojox.data.jsonRestStore dojox.data.jsonQueryRestStore dojox.data.FlickrRestStore dojox.data.AtomReadStore … Интерфейсы Большая часть виджетов форм dojox.Grid …
Ajax Rest Zend Framework Zend_Rest_Route GET /product/ratings/ - indexAction() GET /product/ratings/:id - getAction() POST /product/ratings  - postAction() PUT /product/ratings/:id  - putAction() DELETE /product/ratings/:id  - deleteAction() POST /product/ratings/:id?_method=&quot;PUT&quot;  - putAction() POST /product/ratings/:id?_method=&quot;DELETE&quot;  - deleteAction() Zend_Rest_Controller
Выпуск в эксплуатацию Слой сборки custom.main.js dojo.provide(&quot;custom.main&quot;); (function(){ dojo.require(&quot;dojo.io.script&quot;); dojo.require(&quot;dojo.fx&quot;); dojo.require(&quot;dijit.form.Button&quot;); })();
Выпуск в эксплуатацию Профиль сборки dependencies = { action:&quot;release&quot;, optimize:&quot;shrinksafe&quot;, layerOptimize:&quot;shrinksafe&quot;, copyTests:false, loader:&quot;default&quot;, cssOptimize:&quot;comments&quot;, releaseName:&quot;custom&quot;, layers:[{ name:&quot;custom.main.js&quot;, layerDependencies:[], dependencies:[&quot;custom.main&quot;] }], prefixes:[ [&quot;custom&quot;,&quot;../custom&quot;], [&quot;dojo&quot;,&quot;../dojo&quot;], [&quot;dijit&quot;,&quot;../dijit&quot;] ] };
Выпуск в эксплуатацию Генерация профиля и слоя Zend_Dojo_BuildLayer   автоматически генерирует содержание профиля и содержание слоя на основе данных из  view- хелпера  dojo() . public function buildAction() { $build = new Zend_Dojo_BuildLayer(array( 'view' => $this->view, 'layerScriptPath' => 'custom.main.js', 'layerName' => 'custom.main', )); $profile = $build->generateBuildProfile(); $layerScript = $build->generateLayerScript(); }
Подробнее? Dojo Toolkit Документация http:// api.dojotoolkit.org http:// docs.dojocampus.org Блоги http :// dojotoolkit.org / rss.xml http :// dojocampus.org / content / feed IRC #dojo на irc.freenode.net Список рассылки dojo-interest http :// dojotoolkit.org / mailman / listinfo / dojo-interest
Подробнее? Zend Framework Документация http:// framework.zend.com /manual Wiki http:// framework.zend.com/wiki Блоги http :// devzone.zend.com http :// framework.zend.com IRC #zftalk on irc.freenode.net Списки рассылок http:// framework.zend.com / archives Развитое русскоязычное сообщество http :// zendframework.ru  ( основатель: Александр Махомет)
Вопросы? E-mail :   [email_address] Георгий Туревич,  Wizartech

Rich UI on Dojo Toolkit and Zend Framework

  • 1.
    Создание динамических интерфейсови AJAX- приложений промышленного класса с помощью Dojo Toolkit и Zend Framework Георгий Туревич, Wizartech
  • 2.
    Немного о себеВедущий веб-программист компании Wizartech Более 7-и лет использования PHP и JavaScript Более 2-х лет использования Zend Framework Около 1-го года активного использования Dojo Toolkit (с момента заключения партнерства с Zend Framework) и создания индивидуальных компонентов Принимаю активное участие в развитии сообщества ZendFramework . ru (с момента создания) Модератор русскоязычной группы рассылки «RU DojoToolkit JS Framework» на  Google Groups
  • 3.
    Промышленный? Богатый функционалГибкая архитектура Проверенный код Код библиотек покрыт тестами Собственный инструментарий для тестирования Постоянное развитие и ясное будущее Поддержка от Zend Technologies и Sitepen Мощное сообщество Zend Framework: Adobe, Google, Sitepen, Microsoft, Nirvanix, Strikiron Dojo Toolkit : Sun, IBM, Google, AOL, Uxebu, Sitepen Лицензирование Zend Framework: New BSD License Dojo Toolkit : Modified BSD license \ The Academic Free License 2.1
  • 4.
  • 5.
    Где взять Dojo ? Скачайте напрямую Subversion / Git / Bazaar CDN (Google, AOL , …)
  • 6.
  • 7.
    Вкратце о Core и Base Полезные утилиты Обработка событий Ajax (Restful XHR, script, iframe) Манипулирование узлами Интернационализация Перетаскивание Анимация Абстракция данных Имитация классов и наследования
  • 8.
  • 9.
    Инициализация <html> <head><title> Dojo </title> <script type=&quot;text/javascript&quot; src=&quot;http://o.aolcdn.com/dojo/1.3/dojo.xd.js&quot;> </script> </head> <body> HELLO PHPCONF 2009 !!! </body> </html> Также можно использовать: Другие CDN (помимо AOL и Google можно использовать собственные XD -сборки) Локальные копии Dojo Toolkit
  • 10.
    Конфигурирование <script type=&quot;text/javascript&quot;src=&quot;/dojotoolkit/dojo/dojo.js&quot; djConfig=&quot;isDebug:true,parseOnLoad:true&quot; > </script> Конфигурировать возможно прямо в тэге <script> : Или программным способом (для соответствия стандартам): <script> var djConfig = {isDebug: true, parseOnLoad: true} </script> <script type=&quot;text/javascript&quot; src=&quot;/dojotoolkit/dojo/dojo.js&quot;> </script>
  • 11.
    Система управления пакетамии зависимостями <script> dojo.require(&quot;dojo.fx&quot;); dojo.require(&quot;dojo.io.script&quot;); dojo.registerModulePath(&quot;wlib&quot;, &quot;/js/wlib/&quot;); dojo.require(&quot;wlib.Example&quot;); // /js/wlib/Example.js var exampleObj = new wlib.Example(); </script>
  • 12.
    Система управления пакетамии зависимостями dojo.provide(&quot;wlib.Example&quot;); dojo.declare(&quot;wlib.Example&quot;, null, { constructor: function() { console.log(&quot;HELLO! It is example!&quot;); } }); /js/wlib/Example.js Вывод в консоли Firebug Lite ( упрощенный аналог плагина для FF) :
  • 13.
    dojo.addOnLoad() Интересное вBase и Core События dojo.addOnUnload() <script> var onLoadFunc = function() { console.log('Да! Страница загружена!'); } dojo.addOnLoad(onLoadFunc); </script> <script> var onUnloadFunc = function() { alert('Закрываем страницу'); } dojo.addOnUnload(onUnloadFunc); </script>
  • 14.
    Интересное в Baseи Core События dojo.connect() <a href=&quot;http://phpconf.ru&quot; id=&quot;link&quot;>Все на конференцию</a> <script> dojo.connect(dojo.byId('link'),'onclick', function(evt) { dojo.stopEvent(evt); console.log('Вы щелкнули на ссылку!'); }); </script>
  • 15.
    Интересное в Baseи Core События dojo.connect() / dojo.disconnect() <script> function foo() { console.log('Вызвана функция foo') } function bar() { console.log('Вызвана фукция bar') } var conn = dojo.connect('foo', bar); foo(); console.log('--- Удаляем соединение --- '); dojo.disconnect(conn); foo(); </script>
  • 16.
    Интересное в Baseи Core События dojo.connect() / dojo.disconnect()
  • 17.
    Интересное в Baseи Core События dojo.subscribe(), dojo.unsubscribe(), dojo.publish() <script> function handlerFirst(data) { console.log(&quot;Функция handlerFirst, Данные:&quot;, data); } function handlerSecond(data) { console.log(&quot;Функция handlerSecond, Данные:&quot;, data); } var subscrFirst = dojo.subscribe('mySubscribe', null, handlerFirst); var subscrSecond = dojo.subscribe('mySubscribe', null, handlerSecond); </script>
  • 18.
    Интересное в Baseи Core События dojo.subscribe(), dojo.unsubscribe(), dojo.publish() <script> dojo.publish(&quot;mySubscribe&quot;, [&quot;Привет всем!&quot;]); dojo.publish(&quot;mySubscribe&quot;, [&quot;Пока всем!&quot;]); console.log(&quot; --- Очищаем subscrFirst --- &quot;); dojo.unsubscribe(subscrFirst); dojo.publish(&quot;mySubscribe&quot;, [&quot;Привет всем!&quot;]); dojo.publish(&quot;mySubscribe&quot;, [&quot;Пока всем!&quot;]); </script>
  • 19.
    Интересное в Baseи Core События dojo.subscribe(), dojo.unsubscribe(), dojo.publish()
  • 20.
    Интересное в Baseи Core Ajax Полный Restful набор функций: dojo.xhrGet() dojo.xhrPost() <script> dojo.xhrPost({ url: &quot;./test.php&quot;, handleAs: &quot;text&quot;, content: {a: &quot;1111&quot;, b: &quot;2222&quot;}, load: function(response, ioArgs) { console.log(response); return response; } }); </script> dojo.xhrPut() dojo.xhrDelete()
  • 21.
    Интересное в Baseи Core Ajax test.php <?php print_r($_POST);
  • 22.
    Интересное в Baseи Core Ajax dojo.Deffered (позволяет создавать цепочки функций обратного вызова) <script> function firstCallback(response, ioArgs) { console.log(&quot;Вызван firstCallback : &quot;, response); return response; } function secondCallback(response, ioArgs) { console.log(&quot;Вызван secondCallback : &quot;, response); return response; } </script>
  • 23.
    Интересное в Baseи Core Ajax dojo.Deffered <script> var deffered = dojo.xhrPost({ url: &quot;./test_deffered.php&quot;, handleAs: &quot;json&quot;, content: {a: &quot;1111&quot;, b: &quot;2222&quot;}, load: function(response, ioArgs) {} }); deffered.addCallback(firstCallback); deffered.addCallback(secondCallback); </script> Также есть возможность добавлять: Исключительно обработчики ошибок ( addErrback метод) Универсальные обработчики ( addBoth метод)
  • 24.
    Интересное в Baseи Core Ajax test _ deffered.php <?php echo json_encode($_POST);
  • 25.
    Имитация классов инаследования dojo.declare() <script> dojo.declare(&quot;wlib.ExampleParentFirst&quot;, null, { constructor: function() { console.log(&quot;Вызов конструктора&quot;); } }); dojo.declare(&quot;wlib.ExampleParentSecond&quot;, null, { say: function(message) { console.log(message) } }); </script>
  • 26.
    Имитация классов инаследования dojo.declare() <script> dojo.declare( &quot;wlib.ExampleParentChild&quot;, [wlib.ExampleParentFirst, wlib.ExampleParentSecond], { sayBy: function() { this.say(&quot;Всем пока!&quot;) } } ); var child = new wlib.ExampleParentChild(); child.sayBy(); </script>
  • 27.
    Имитация классов инаследования dojo.declare()
  • 28.
    Имитация классов инаследования dojo.extend() <script> dojo.extend(wlib.ExampleParentChild, { sayHello: function() { this.say(&quot;Всем привет!&quot;); } }) ; var child = new wlib.ExampleParentChild(); child.sayHello(); child.sayBy(); </script>
  • 29.
    Имитация классов инаследования dojo.mixin() <script> var obj = { firstName: &quot;Иван&quot;, lastName: &quot;Петров&quot; }; var emp = dojo.mixin(obj, { sayName: function() { console.log( &quot;Меня зовут &quot; + this.firstName + &quot; &quot; + this.lastName ); } }); emp.sayName(); </script>
  • 30.
    Имитация классов инаследования dojo.hitch() <script> function sayName() { console.log( &quot;Меня зовут &quot; + this.firstName + &quot; &quot; + this.lastName ); } var obj = { firstName: &quot;Иван&quot;, lastName: &quot;Петров&quot; }; var callback = dojo.hitch(obj, sayName); callback(); </script>
  • 31.
  • 32.
    Что такое Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.)
  • 33.
  • 34.
    Что такое Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.) Виджеты компоновки ( Content pane, Accordion / Tab / Stack / Border - контейнеры )
  • 35.
  • 36.
    Что такое Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.) Виджеты компоновки ( Content pane, Accordion / Tab / Stack / Border - контейнеры ) Виджеты приложения (деревья, прогресс-бар, диалоги, меню, WYSIWYG и т . д.)
  • 37.
  • 38.
    Что такое Dijit ? Система виджетов Dojo Богатый набор готовых виджетов Элементы форм (текстовые поля, кнопки, выпадающие элементы, слайдеры и т.д.) Виджеты компоновки ( Content pane, Accordion / Tab / Stack / Border - контейнеры ) Виджеты приложения (деревья, прогресс-бар, диалоги, меню, WYSIWYG и т . д.) Доступность ( Accessibility (a11y)) Шаблонность (встроенный шаблонизатор) Готовые темы оформления (tundra, soria, nihilo, noir)
  • 39.
    Инициализация виджетов <scriptsrc=&quot;/dojotoolkit/dojo/dojo.js&quot; djConfig=&quot;isDebug: true, parseOnLoad: true &quot; ></script> <script> dojo.require(&quot; dijit.form.Button &quot;); </script> <link id=&quot;themeStyles&quot; rel=&quot;stylesheet&quot; href=&quot; /dojotoolkit/dijit/themes/tundra/tundra.css &quot;> В секции <head> : Устанавливаем parseOnLoad в true Подключаем нужные виджеты Подключаем тему оформления
  • 40.
    Инициализация виджетов <divclass=&quot;tundra&quot;> <button id=&quot;buttonHello&quot;></button> <button dojoType=&quot;dijit.form.Button&quot;> Щелкни по мне! </button> </div> <script> var button = new dijit.form.Button({ label: &quot;Привет!&quot;, name: &quot;programmatic&quot; }, &quot;buttonHello&quot;); </script> В секции <body> :
  • 41.
    Инициализация виджетов Однакнопка инициализирована программным способом Вторая кнопка инициализирована декларативным способом
  • 42.
    Возможности расширения Переопределениеметодов жизненного цикла constructor() (конструктор) postMixInProperties() (вызывается после формирования структуры виджета) buildRendering() (генерирует визуальное отображение виджета) postCreate() (вызывается сразу после создания визуального отображения) startup() (вызывается после создания всех дочерних виджетов и самого виджета) Шаблон Можно встраивать в код класса Можно выносить в отдельный файл Языковые файлы Можно встраивать в код класса Можно выносить в отдельный файл
  • 43.
  • 44.
    Dojox Dojox — собрание расширенных, дополнительных и экспериментальных компонентов (Extensions, Extras, Experiments) Состав: Расширения Dijit (dojox.widget, dojox.layout, dojox.form) Дополнительная анимация: dojox.fx (Morph, Text, Extras, ...) Виджеты изображений (FlickrBadge, Lightbox (Nano), SlideShow, ...) Расширенный IO (RPC, REST, SMD, ScriptFrame, ...) И многое другое …
  • 45.
    Dojox Кроссбраузерная векторнаяграфика: GFX API Charting GFX 2D / 3D GFX -анимации
  • 46.
  • 47.
  • 48.
    Абстракция работыс данными Все типы хранилищ реализуют один или несколько интерфейсов: dojo.data.api.Read (чтение, поиск, сортировка и фильтрация элементов данных) dojo.data.api.Write (создание, удаление, обновление элементов данных) dojo.data.api.Identity (доступ к элементам по средствам уникальных идентификаторов) dojo.data.api.Notification (уведомление о таких событиях, как создание, удаление или обновление элементов данных)
  • 49.
    Абстракция работыс данными Dojo dojo.data.ItemFileReadStore dojo.data.ItemFileWriteStore Dojox AtomReadStore CouchDBRestStore CssRuleStore CsvStore FileStore FlickrRestStore/FlickrStore GoogleFeedStore GoogleSearchStore HtmlStore jsonRestStore QueryReadStore ServiceStore S3Store WikipediaStore XmlStore И другие …
  • 50.
  • 51.
    Подготовка к выпускув эксплуатацию В пакете Dojo Toolkit поставляется утилита ShrinkSafe (Java), которая реализует следующие функции: Уменьшение количества HTTP-запросов Объедение файлов с классами, шаблонами, языковыми данными Уменьшение размера JavaScript-файлов Удаление комментариев и пробелов Сокращение наименований переменных CSS-оптимизация Объединение @import-файлов в один Удаление комментариев Опции StripConsole X-Domain-сборки (свой CDN)
  • 52.
    D.O.H Система модульноготестирования Поддерживает assert*, buildUp, tearDown– методы, тестирование синхронных и асинхронных запросов, включает в себя подсистему тестирования визуальных компонентов doh.robot .
  • 53.
    Интеграция DojoToolkit и Zend Framework Программная настройка Dojo -окружения Автоматизация работы с виджетами Генерация спец. форматов данных Упрощение выпуска в эксплуатацию
  • 54.
  • 55.
    Программная настройка Dojo -окружения Типичный код в <head> секции для настройки Dojo : <style type=&quot;text/css&quot;> @import &quot;/js/dojo-toolkit/dijit/themes/tundra/tundra.css&quot;; </style> <script type=&quot;text/javascript&quot;> var djConfig = {&quot;isDebug&quot;:true,&quot;parseOnLoad&quot;:true}; </script> <script type=&quot;text/javascript&quot; src=&quot;/js/dojo-toolkit/dojo/dojo.js&quot;></script> <script type=&quot;text/javascript&quot;> dojo.require(&quot;dojo.io.script&quot;); dojo.require(&quot;dojo.fx&quot;); dojo.require(&quot;dijit.form.Button&quot;); </script>
  • 56.
    Программная настройка Dojo -окружения Конфигурация с помощью dojo() view- хелпера: <?=$this->dojo() ->enable() ->setDjConfig( array('isDebug' => true, 'parseOnLoad' => true) ) ->setLocalPath('/js/dojo-toolkit/dojo/dojo.js') ->addStyleSheetModule('dijit.themes.tundra') ->requireModule( array('dojo.io.script', 'dojo.fx', 'dijit.form.Button') )?>
  • 57.
    Программная настройка Dojo -окружения Шаг в будущее  В активной разработке плагин бустрапа Zend_Application_Resource_Dojo, с помощью которого: <?=$this->dojo() ?> И в application.ini : resources.dojo.djConfig.isDebug = 1 resources.dojo.djConfig.parseOnLoad = 1 resources.dojo.localPath = &quot;/js/dojo-toolkit/dojo/dojo.js&quot; resources.dojo.requireModule[] = &quot;dojo.io.script&quot; resources.dojo.requireModule[] = &quot;dojo.fx&quot; resources.dojo.requireModule[] = &quot;dijit.form.Button&quot; В макете указываем:
  • 58.
    Работа с виджетамиView- хелперы В шаблоне: <h1>Форма</h1> <div class=&quot;tundra&quot;> <form> <?=$this->editor('editor')?> <?=$this->button( 'send', 'Отправить')?> </form> </div>
  • 59.
    Работа с виджетамиЭлементы форм В контроллере: $form = new Zend_Dojo_Form(); $form->addElement('editor', 'editor'); $form->addElement( 'button', 'send', array('label' => 'Отправить') ); $this->view->form = $form; <h1>Форма</h1> <div class=&quot;tundra&quot;> <?=$this->form?> </div> В шаблоне:
  • 60.
    Работа с виджетамиСостав компонентов В состав элементов для Zend_Dojo_Form входят классы для большинства виджетов формы Так же реализованы view- хелперы и декораторы для форм, которые упрощают работу с виджетами компоновки: AccordionContainer AccordionPane BorderContainer SplitContainer StackContainer TabContainer ContentPane
  • 61.
    Ajax Zend_Dojo_Data Формируемформу: public function dojoDataExampleAction() { $form = new Zend_Dojo_Form(); $form->addElement( 'FilteringSelect', 'city', array( 'label' => 'City', 'storeId' => 'cityStore', 'storeType' => 'dojo.data.ItemFileReadStore', 'storeParams' => array( 'url' => '/json/simple-city-store/', ), 'dijitParams' => array( 'searchAttr' => 'name', ) ) ); $this->view->form = $form; }
  • 62.
    Ajax Zend_Dojo_Data Отдаемданные в формате dojo.data : public function simpleCityStoreAction() { $data = array( array('id' => 1, 'name' => 'Волгоград'), array('id' => 2, 'name' => 'Москва'), array('id' => 3, 'name' => 'Минск'), array('id' => 4, 'name' => 'Мурманск') ); $dojoData = new Zend_Dojo_Data('id', $data); echo $dojoData; }
  • 63.
    Ajax Zend_Dojo_Data Отдаемданные в формате dojo.data : { &quot;identifier&quot;:&quot;id&quot;, &quot;items&quot;:[ {&quot;id&quot;:1,&quot;name&quot;:&quot;Волгоград&quot;}, {&quot;id&quot;:2,&quot;name&quot;:&quot;Москва&quot;}, {&quot;id&quot;:3,&quot;name&quot;:&quot;Минск&quot;}, {&quot;id&quot;:4,&quot;name&quot;:&quot;Мурманск&quot;} ] }
  • 64.
    Ajax Zend_Dojo_Data Вшаблоне: <div class=&quot;tundra&quot;><?=$this->form?></div> Вуаля!
  • 65.
    Ajax JSON-RPC Клиентскаячасть (в шаблоне): <? $this->dojo()->requireModule(&quot;dojo.rpc.JsonService&quot;); ?> <? $this->dojo()->onLoadCaptureStart(); ?> function() { var o = { &quot;serviceType&quot;: &quot;JSON-RPC&quot;, &quot;serviceUrl&quot;: &quot;/json/rpc-server&quot;, &quot;methods&quot;: [{ &quot;name&quot;: &quot;sum&quot;, &quot;parameters&quot;: [ {name: &quot;numbers&quot;} ] }] } ... } <? $this->dojo()->onLoadCaptureEnd(); ?>
  • 66.
    Ajax JSON-RPC Клиентскаячасть (в шаблоне): ... var rpcObject = new dojo.rpc.JsonService(o) var sum = rpcObject.sum([4,8,15,16,23,42]); sum.addCallback(function(response) { console.log(&quot;Сумма чисел: &quot;, response) }); Запрос: {&quot;params&quot;:[[4,8,15,16,23,42]],&quot;method&quot;:&quot;sum&quot;,&quot;id&quot;:1}
  • 67.
    Ajax JSON-RPC Сервернаячасть ( модель): class Default_Model_RpcTest { function sum($numbers) { return array_sum($numbers); } }
  • 68.
    Ajax JSON-RPC Сервернаячасть (контроллер): public function rpcServerAction() { $server = new Zend_Json_Server(); $server->setClass('Default_Model_RpcTest'); $server->handle(); } Результат:
  • 69.
    Ajax Rest DojoToolkit Хранилища dojox.data.jsonRestStore dojox.data.jsonQueryRestStore dojox.data.FlickrRestStore dojox.data.AtomReadStore … Интерфейсы Большая часть виджетов форм dojox.Grid …
  • 70.
    Ajax Rest ZendFramework Zend_Rest_Route GET /product/ratings/ - indexAction() GET /product/ratings/:id - getAction() POST /product/ratings - postAction() PUT /product/ratings/:id - putAction() DELETE /product/ratings/:id - deleteAction() POST /product/ratings/:id?_method=&quot;PUT&quot; - putAction() POST /product/ratings/:id?_method=&quot;DELETE&quot; - deleteAction() Zend_Rest_Controller
  • 71.
    Выпуск в эксплуатациюСлой сборки custom.main.js dojo.provide(&quot;custom.main&quot;); (function(){ dojo.require(&quot;dojo.io.script&quot;); dojo.require(&quot;dojo.fx&quot;); dojo.require(&quot;dijit.form.Button&quot;); })();
  • 72.
    Выпуск в эксплуатациюПрофиль сборки dependencies = { action:&quot;release&quot;, optimize:&quot;shrinksafe&quot;, layerOptimize:&quot;shrinksafe&quot;, copyTests:false, loader:&quot;default&quot;, cssOptimize:&quot;comments&quot;, releaseName:&quot;custom&quot;, layers:[{ name:&quot;custom.main.js&quot;, layerDependencies:[], dependencies:[&quot;custom.main&quot;] }], prefixes:[ [&quot;custom&quot;,&quot;../custom&quot;], [&quot;dojo&quot;,&quot;../dojo&quot;], [&quot;dijit&quot;,&quot;../dijit&quot;] ] };
  • 73.
    Выпуск в эксплуатациюГенерация профиля и слоя Zend_Dojo_BuildLayer автоматически генерирует содержание профиля и содержание слоя на основе данных из view- хелпера dojo() . public function buildAction() { $build = new Zend_Dojo_BuildLayer(array( 'view' => $this->view, 'layerScriptPath' => 'custom.main.js', 'layerName' => 'custom.main', )); $profile = $build->generateBuildProfile(); $layerScript = $build->generateLayerScript(); }
  • 74.
    Подробнее? Dojo ToolkitДокументация http:// api.dojotoolkit.org http:// docs.dojocampus.org Блоги http :// dojotoolkit.org / rss.xml http :// dojocampus.org / content / feed IRC #dojo на irc.freenode.net Список рассылки dojo-interest http :// dojotoolkit.org / mailman / listinfo / dojo-interest
  • 75.
    Подробнее? Zend FrameworkДокументация http:// framework.zend.com /manual Wiki http:// framework.zend.com/wiki Блоги http :// devzone.zend.com http :// framework.zend.com IRC #zftalk on irc.freenode.net Списки рассылок http:// framework.zend.com / archives Развитое русскоязычное сообщество http :// zendframework.ru ( основатель: Александр Махомет)
  • 76.
    Вопросы? E-mail : [email_address] Георгий Туревич, Wizartech