rich ui on dojo toolkit and zend framework

Post on 17-Dec-2014

3.788 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Презентация мастер-класса "Создание динамических пользовательских интерфейсов и AJAX-приложений промышленного класса с помощью Dojo Toolkit и Zend Framework"

TRANSCRIPT

Создание динамических интерфейсови 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 ToolkitCore и Base

Инициализация

<html> <head> <title>Dojo</title> <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.3/dojo.xd.js"> </script> </head><body>HELLO PHPCONF 2009 !!!</body></html>

Также можно использовать:• Другие CDN (помимо AOL и Google можно использовать собственные

XD-сборки)• Локальные копии Dojo Toolkit

Конфигурирование

<script type="text/javascript" src="/dojotoolkit/dojo/dojo.js" djConfig="isDebug:true,parseOnLoad:true"></script>

Конфигурировать возможно прямо в тэге <script>:

Или программным способом (для соответствия стандартам):

<script>

var djConfig = {isDebug: true, parseOnLoad: true}

</script>

<script type="text/javascript"

src="/dojotoolkit/dojo/dojo.js">

</script>

Система управленияпакетами и зависимостями

<script> dojo.require("dojo.fx"); dojo.require("dojo.io.script");

dojo.registerModulePath("wlib", "/js/wlib/"); dojo.require("wlib.Example"); // /js/wlib/Example.js

var exampleObj = new wlib.Example();</script>

Система управленияпакетами и зависимостями

dojo.provide("wlib.Example");

dojo.declare("wlib.Example", null, { constructor: function() { console.log("HELLO! It is example!"); }});

/js/wlib/Example.js

Вывод в консоли Firebug Lite (упрощенный аналог плагина для FF):

dojo.addOnLoad()

dojo.addOnUnload()

<script>

var onLoadFunc = function() {

console.log('Да! Страница загружена!');

}

dojo.addOnLoad(onLoadFunc);

</script>

<script>

var onUnloadFunc = function() {

alert('Закрываем страницу');

}

dojo.addOnUnload(onUnloadFunc);

</script>

Интересное в Base и CoreСобытия

Интересное в Base и CoreСобытия

dojo.connect()

<a href="http://phpconf.ru" id="link">Все на конференцию</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("Функция handlerFirst, Данные:", data);

}

function handlerSecond(data) {

console.log("Функция handlerSecond, Данные:", 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("mySubscribe", ["Привет всем!"]);

dojo.publish("mySubscribe", ["Пока всем!"]);

console.log(" --- Очищаем subscrFirst --- ");

dojo.unsubscribe(subscrFirst);

dojo.publish("mySubscribe", ["Привет всем!"]);

dojo.publish("mySubscribe", ["Пока всем!"]);

</script>

Интересное в Base и CoreСобытия

dojo.subscribe(), dojo.unsubscribe(), dojo.publish()

Интересное в Base и CoreAjax

Полный Restful набор функций:• dojo.xhrGet()• dojo.xhrPost()

<script>

dojo.xhrPost({

url: "./test.php",

handleAs: "text",

content: {a: "1111", b: "2222"},

load: function(response, ioArgs) {

console.log(response);

return response;

}

});

</script>

• dojo.xhrPut()• dojo.xhrDelete()

Интересное в Base и CoreAjax

test.php

<?php

print_r($_POST);

Интересное в Base и CoreAjax

dojo.Deffered (позволяет создавать цепочки функций обратного вызова)

<script>

function firstCallback(response, ioArgs) {

console.log("Вызван firstCallback:", response);

return response;

}

function secondCallback(response, ioArgs) {

console.log("Вызван secondCallback:", response);

return response;

}

</script>

Интересное в Base и CoreAjax

<script>

var deffered = dojo.xhrPost({

url: "./test_deffered.php",

handleAs: "json",

content: {a: "1111", b: "2222"},

load: function(response, ioArgs) {}

});

deffered.addCallback(firstCallback);

deffered.addCallback(secondCallback);

</script>

dojo.Deffered

Также есть возможность добавлять:• Исключительно обработчики ошибок (addErrback метод)• Универсальные обработчики (addBoth метод)

Интересное в Base и CoreAjax

test_deffered.php

<?php

echo json_encode($_POST);

Имитация классови наследования

dojo.declare()

<script>

dojo.declare("wlib.ExampleParentFirst", null, {

constructor: function() {

console.log("Вызов конструктора");

}

});

dojo.declare("wlib.ExampleParentSecond", null, {

say: function(message) {

console.log(message)

}

});

</script>

Имитация классови наследования

<script>

dojo.declare(

"wlib.ExampleParentChild",

[wlib.ExampleParentFirst, wlib.ExampleParentSecond],

{

sayBy: function() {

this.say("Всем пока!")

}

}

);

var child = new wlib.ExampleParentChild();

child.sayBy();

</script>

dojo.declare()

Имитация классови наследования

dojo.declare()

Имитация классови наследования

dojo.extend()

<script>

dojo.extend(wlib.ExampleParentChild, { sayHello: function() {

this.say("Всем привет!");

}

});

var child = new wlib.ExampleParentChild();

child.sayHello();

child.sayBy();

</script>

Имитация классови наследования

dojo.mixin()

<script>

var obj = { firstName: "Иван", lastName: "Петров" };

var emp = dojo.mixin(obj, {

sayName: function() {

console.log(

"Меня зовут " + this.firstName + " "

+ this.lastName

);

}

});

emp.sayName();

</script>

Имитация классови наследования

dojo.hitch()

<script>

function sayName() {

console.log(

"Меня зовут " + this.firstName + " "

+ this.lastName

);

}

var obj = { firstName: "Иван", lastName: "Петров" };

var callback = dojo.hitch(obj, sayName);

callback();

</script>

Dojo ToolkitDijit

Что такое 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="/dojotoolkit/dojo/dojo.js"

djConfig="isDebug: true, parseOnLoad: true"

></script>

<script>

dojo.require("dijit.form.Button");

</script>

<link id="themeStyles" rel="stylesheet" href="/dojotoolkit/dijit/themes/tundra/tundra.css">

В секции <head>:• Устанавливаем parseOnLoad в true• Подключаем нужные виджеты• Подключаем тему оформления

Инициализация виджетов

<div class="tundra">

<button id="buttonHello"></button>

<button dojoType="dijit.form.Button">

Щелкни по мне!

</button>

</div>

<script>

var button = new dijit.form.Button({

label: "Привет!",

name: "programmatic"

}, "buttonHello");

</script>

В секции <body>:

Инициализация виджетов

• Одна кнопка инициализирована программным способом• Вторая кнопка инициализирована декларативным способом

Возможности расширения

• Переопределение методов жизненного цикла– constructor() (конструктор)– postMixInProperties() (вызывается после формирования структуры виджета)– buildRendering() (генерирует визуальное отображение виджета)– postCreate() (вызывается сразу после создания визуального отображения)– startup() (вызывается после создания всех дочерних виджетов и самого

виджета)

• Шаблон– Можно встраивать в код класса– Можно выносить в отдельный файл

• Языковые файлы– Можно встраивать в код класса– Можно выносить в отдельный файл

Dojo ToolkitDojox

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 ToolkitUtil

Подготовка к выпускув эксплуатацию

В пакете 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-окружения

<style type="text/css">

@import "/js/dojo-toolkit/dijit/themes/tundra/tundra.css";

</style>

<script type="text/javascript">

var djConfig = {"isDebug":true,"parseOnLoad":true};

</script>

<script type="text/javascript"

src="/js/dojo-toolkit/dojo/dojo.js"></script>

<script type="text/javascript">

dojo.require("dojo.io.script");

dojo.require("dojo.fx");

dojo.require("dijit.form.Button");

</script>

Типичный код в <head> секции для настройки Dojo:

Программная настройка Dojo-окружения

<?=$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() view-хелпера:

Программная настройка Dojo-окружения

<?=$this->dojo()?>

Шаг в будущее В активной разработке плагин бустрапаZend_Application_Resource_Dojo, с помощью которого:

И в application.ini:

resources.dojo.djConfig.isDebug = 1

resources.dojo.djConfig.parseOnLoad = 1

resources.dojo.localPath = "/js/dojo-toolkit/dojo/dojo.js"

resources.dojo.requireModule[] = "dojo.io.script"

resources.dojo.requireModule[] = "dojo.fx"

resources.dojo.requireModule[] = "dijit.form.Button"

В макете указываем:

Работа с виджетамиView-хелперы

<h1>Форма</h1>

<div class="tundra">

<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="tundra">

<?=$this->form?>

</div>

В шаблоне:

Работа с виджетамиСостав компонентов

• В состав элементов для Zend_Dojo_Form входят классы для большинства виджетов формы

• Так же реализованы view-хелперы и декораторы для форм, которые упрощают работу с виджетами компоновки:– AccordionContainer– AccordionPane– BorderContainer– SplitContainer– StackContainer– TabContainer– ContentPane

AjaxZend_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;

}

Формируем форму:

AjaxZend_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;

}

Отдаем данные в формате dojo.data:

AjaxZend_Dojo_Data

Отдаем данные в формате dojo.data:

{

"identifier":"id",

"items":[

{"id":1,"name":"Волгоград"},

{"id":2,"name":"Москва"},

{"id":3,"name":"Минск"},

{"id":4,"name":"Мурманск"}

]

}

AjaxZend_Dojo_Data

В шаблоне:

<div class="tundra"><?=$this->form?></div>

Вуаля!

AjaxJSON-RPC

Клиентская часть (в шаблоне):

<? $this->dojo()->requireModule("dojo.rpc.JsonService"); ?>

<? $this->dojo()->onLoadCaptureStart(); ?>

function() {

var o = {

"serviceType": "JSON-RPC",

"serviceUrl": "/json/rpc-server",

"methods": [{

"name": "sum",

"parameters": [

{name: "numbers"}

]

}]

}

...

}

<? $this->dojo()->onLoadCaptureEnd(); ?>

AjaxJSON-RPC

Клиентская часть (в шаблоне):

...

var rpcObject = new dojo.rpc.JsonService(o)

var sum = rpcObject.sum([4,8,15,16,23,42]);

sum.addCallback(function(response) {

console.log("Сумма чисел: ", response)

});

Запрос:

{"params":[[4,8,15,16,23,42]],"method":"sum","id":1}

AjaxJSON-RPC

Серверная часть (модель):

class Default_Model_RpcTest

{

function sum($numbers)

{

return array_sum($numbers);

}

}

AjaxJSON-RPC

Серверная часть (контроллер):

public function rpcServerAction()

{

$server = new Zend_Json_Server();

$server->setClass('Default_Model_RpcTest');

$server->handle();

}

Результат:

AjaxRest

• Dojo Toolkit• Хранилища

• dojox.data.jsonRestStore• dojox.data.jsonQueryRestStore• dojox.data.FlickrRestStore• dojox.data.AtomReadStore• …

• Интерфейсы• Большая часть виджетов форм• dojox.Grid• …

AjaxRest

• 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="PUT" - putAction()• POST /product/ratings/:id?_method="DELETE" - deleteAction()

• Zend_Rest_Controller

Выпуск в эксплуатациюСлой сборки

dojo.provide("custom.main");

(function(){

dojo.require("dojo.io.script");

dojo.require("dojo.fx");

dojo.require("dijit.form.Button");

})();

custom.main.js

Выпуск в эксплуатациюПрофиль сборки

dependencies = {

action:"release", optimize:"shrinksafe",

layerOptimize:"shrinksafe", copyTests:false,

loader:"default", cssOptimize:"comments",

releaseName:"custom",

layers:[{

name:"custom.main.js",

layerDependencies:[],

dependencies:["custom.main"]

}],

prefixes:[

["custom","../custom"],

["dojo","../dojo"],

["dijit","../dijit"]

]

};

Выпуск в эксплуатациюГенерация профиля и слоя

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();

}

Zend_Dojo_BuildLayer автоматически генерирует содержание профиляи содержание слоя на основе данных из view-хелпера dojo().

Подробнее?

• 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: georgy.turevich@wizartech.ru

Георгий Туревич, Wizartech

top related