Вбудуйте Ajax в Web-додаток на основі Rails (исходники), HTML, XML, DHTML, Інтернет-технології, статті

Якщо ви не чули про Rails, то повертайтеся з подорожі на планету Зортон, так як тільки там в цьому році ви могли бути і не чути про Ruby on Rails. Rails найбільш привабливий тим, що дозволяє швидко розробити і запустити додаток з усіма функціональними можливостями. Інтеграція з Rails, вбудована в бібліотеку Prototype.js для Ajax, робить простий швидку розробку так званих багатих інтернет-додатків.


У цій статті будуть розглянуті кроки зі створення програми на Rails. Потім увагу буде приділено використанню можливостей Ajax для побудови JavaScript-коду, зчитує і записує дані на сервер.


Трохи про Rails


І все-таки, що таке Rails? Rails – це платформа для Web-додатків, в основі якої лежить мова програмування Ruby. Ruby популярний вже близько 10 років. Так само як Perl і Python, він має відкриті вихідні коди і є гнучким мовою, що пропонує повну підтримку об’єктно-орієнтованого програмування.


Rails – це програмна оболонка, яка визначає необхідні моделі Web-додатки, такі як Model-View-Controller (MVC). В даному випадку, Модель (Model) представлена ​​набором об’єктів ActiveRecord, які відповідають таблицям в базі даних. Складова Контролер (Controller) – це клас Ruby з методами для кожної операції, виконуваної в даній Моделі. Вид (View) зазвичай представлений HTML-кодом, згенерованих за допомогою шаблону ERB (ERB є вбудованим в Ruby пакетом текстових шаблонів), який, по суті, схожий на код PHP або JavaServer Pages (JSP). Вид також може бути кодом XML, текстом, JavaScript-кодом, зображеннями або тим, що вам подобається.


Коли користувач запитує сторінку Web-додатки на Rails, URL відсилається через систему маршрутизатора, яка відправляє запит до Контролеру. Контролер запитує дані з Моделі і поправляє їх в Вид для форматування.


Коли ви створюєте додаток на Rails, система автоматично генерує набір каталогів і стартових файлів. Серед них каталоги для файлів JavaScript, які поставляються з системою (включаючи бібліотеку Prototype.js), каталоги для Видів, Моделей і контролерів і навіть місце для додаткових модулів, які можна завантажити у інших розробників.


Початок роботи з Rails


Найпростіший шлях для початку розробки Rails-додатки – це використання однієї з готових збірок систем Rails. Якщо ви працюєте в Microsoft ® Windows ®, я б рекомендував використовувати Instant Rails. На Macintosh “е – я великий шанувальник програми Locomotive 2. Обидві програми написані на мові Ruby, мають структуру Rails, Web-сервери, і вбудований MySQL. Після досить об’ємною завантаження можна приступати до створення нових додатків на Rails.


Для цієї статті я створив новий додаток – базу даних рецептів, яку назвав Recipe. В ньому буде потрібно лише одна таблиця. В лістингу 1 показана міграція бази даних для програми Recipe.


Лістинг 1. Перенесення бази даних




                 class
CreateRecipes < ActiveRecord::Migration def self.up create_table ( :recipes,
:options => “ENGINE=InnoDB” ) do /t/ t.column :name, :string,
:null => false t.column :description, :text, :null => false t.column
:ingredients, :text, :null => false t.column :instructions, :text, :null
=> false end end def self.down drop_table :recipes end end

База даних містить тільки одну таблицю: recipes. У таблиці п’ять полів: name, description, ingredients, instructions і п’яте поле – унікальний ідентифікатор, який автоматично підтримує інфраструктура Rails.


Таблиця готова, її необхідно помістити в об’єкт ActiveRecord. Цей об’єкт показаний в лістингу 2.


Лістинг 2. Модель Recipe




                 class Recipe
< ActiveRecord::Base validates_presence_of :name validates_presence_of
:description validates_presence_of :ingredients validates_presence_of :instructions
end

Базовий клас ActiveRecord відповідає за доступ до бази даних: запитів до таблиць, а також вставки, оновлення та видалення записів. В даному випадку я додаю перевірки до окремих полях. Я повідомляю Rails, що в кожному полі повинні міститися ці дані.


Форми Ajax


На першому кроці побудови програми Recipe потрібно розробити спосіб додавання рецептів в базу даних. Спочатку я покажу стандартний метод створення базової HTML-форми в Rails для вирішення даної проблеми. Він починається з класу RecipesController, Показаного в лістингу 3.


Лістинг 3. Recipes_controller.rb





class RecipesController < ApplicationController def add @recipe = Recipe.new
if request.post? @recipe.name = params[:recipe][:name] @recipe.description =
params[:recipe][:description] @recipe.ingredients = params[:recipe][:ingredients]
@recipe.instructions = params[:recipe][:instructions] @recipe.save end end end

Заданий тільки один метод – add, Який починається зі створення порожнього об’єкта Recipe. Потім він додає параметри і намагається їх зберегти, якщо від клієнта надходить відповідний запит.


Шаблон ERB для цієї сторінки показаний в лістингу 4.


Лістинг 4. Add.rhml





<html> <body> <%= error_messages_for
“recipe” %><br/> <%= start_form_tag
%> <table>
<tr><td>Name</td>
<td><%= text_field :recipe, :name
%></td></tr>
<tr><td>Description</td>
<td><%= text_area :recipe, :description, :rows => 3
%></td></tr>
<tr><td>Ingredients</td>
<td><%= text_area :recipe, :ingredients, :rows => 3
%></td></tr>
<tr><td>Instructions</td>
<td><%= text_area :recipe, :instructions, :rows => 3
%></td></tr> </table> <%=
submit_tag “Add” %> <%= end_form_tag %>
</body> </html>

Сторінка починається з повідомлень про помилки об’єкта recipe. Вони будуть підставлені, якщо дані, введені користувачем, не пройдуть перевірку на відповідність об’єкту Моделі Recipe. Потім сторінка запускає тег <form>, Об’єкти text_field і text_area для кожного поля, тег <submit> і закінчення форми.


Це дуже стандартний Rails. Це захищене, безпечно, працює в будь-якому браузері і точно відображається в HTML для клієнта. Але я хочу Web 2.0, а разом з ним і Ajax. Отже, що мені потрібно змінити?


З боку Контролера код для методу add() змінюється радикально, як показано в лістингу 5.


Лістинг 5. Recipes_controller.rb





class RecipesController < ApplicationController def add end def add_ajax
Recipe.create( { :name => params[:recipe][:name], :description =>
params[:recipe][:description], :ingredients => params[:recipe][:ingredients],
:instructions => params[:recipe][:instructions] } ) end end

Метод add() більше нічого не робить, тому що з приходять від клієнта даними тепер працює новий метод add_ajax().


З боку шаблону зміни мінімальні, що видно в лістингу 6.


Лістинг 6. Тема add.rhtml





<html> <head> <%= javascript_include_tag
:defaults %> </head> <body> <div
id=”counter”></div> <%=
form_remote_tag :url => { :action => “add_ajax” },
:complete => “document.forms[0].reset();”, :update
=> “counter” %> <table>
<tr><td>Name</td>

На початку файлу я додав новий HTML-розділ, що містить посилання на файли JavaScript в Rails. Ці файли складають систему Prototype.js, яка виконує більшу частину роботи Ajax.


Після цього я додаю тег <div>, Званий лічильником (counter), який зберігає значення, що повертається запиту Ajax. В цьому немає великої потреби, але є гарним тоном, коли користувач отримує певну реакцію у відповідь.


І нарешті, я змінюю старий виклик start_form_tag на form_remote_tag. form_remote_tag приймає кілька параметрів, найбільш важливим з яких є url, Що визначає, куди відправляти дані. Другий – кінцевий обробник, що містить код JavaScript, який виконується після завершення запиту Ajax. В даному випадку я очищаю форму, щоб користувач міг ввести ще один рецепт. Потім я використовую параметр update, Вказуючи Rails, куди пересилати вихідні дані з add_ajax.


Також мені потрібен шаблон для методу add_ajax(). Лістинг 7 показує цей шаблон.


Лістинг 7. Add_ajax.rhtml




                 <%=
Recipe.find(:all).length %> recipes now in database

І. … це все. Ні, правда! Це кінець. Це все, що було потрібно для міграції стандартної форми HTML на форму Ajax в Rails. Рисунок 1 показують готову для заповнення форму, засновану на Ajax.


Рисунок 1. Форма в Ajax
Форма в Ajax

Наступний крок – поекспериментувати з більш динамічною інтерактивністю, наприклад, з динамічним пошуком за допомогою Ajax.


Динамічний пошук в Ajax


Prototype.js забезпечує функціональність перегляду полів і форм на сторінці. Я використовую цю функціональність для роботи з текстовим полем пошуку, в яке я можу ввести частину рецепта. Потім файл запускає метод пошуку в RecipesController, Який видає результати в теге <div> під текстовим полем. Давайте почнемо з оновленого RecipesController, Показаного в лістингу 8.


Лістинг 8. Recipes_controller.rb





class RecipesController < ApplicationController … def index end def
search_ajax @recipes = Recipe.find( :all, :conditions => [ “name
LIKE ?”, “%#{params[:recipe][:name]}%” ] ) render
:layout=>false end end

Метод index() інтерпретує форму HTML. Метод search_ajax() знаходить рецепти, відповідні параметру пошуку, і відсилає дані в шаблон ERB для форматування. Шаблон index.rtml показаний в лістингу 9.


Лістинг 9. Index.rhtml





<html> <head> <%= javascript_include_tag
:defaults %> </head> <body> <%= form_tag
nil, { :id => “search_form” } %> <%=
text_field “recipe”, “name” %> <%=
end_form_tag %> <div id=”recipe”>
</div> <%= observe_form :search_form, :frequency => 0.5,
:update => “recipe”, :url => { :action =>
“search_ajax” } %> </body>
</html>

На початку лістингу 9 я знову підключаю бібліотеки JavaScript. Після цього я створюю форму form з полем пошуку та тегом <div> для відображення результатів пошуку. І в кінці я викликаю допоміжний метод observe_form(), Який створює код JavaScript, що відслідковує зміни у формі і відсилає дані з форми в метод search_ajax(). Потім результати роботи методу поміщаються в recipe <div>.


Код для форми search_ajax.rhtml показаний в лістингу 10.


Лістинг 10. Search_ajax.rhtml





<% @recipes.each { /r/ %> <h1><%= r.name
%></h1> <p><%= r.description
%></p> <% } %>

Так як пошук може повернути безліч результатів, я роблю цикл за списком рецептів і виводжу їх імена і описи.


Коли я відкриваю сайт в браузері і набираю в пошуковому рядку apple, Я знаходжу рецепт яблучного коктейлю (apple cobbler), як показано на малюнку 2.


Рисунок 2. Динамічний пошук в Ajax
Динамічний пошук в Ajax

Це все, що стосується основ. Але що якщо я хочу отримати більше інформації про рецепт яблучного коктейля? Чи можу я використовувати Ajax для отримання списку інгредієнтів і інструкцій на вимогу? Я радий, що ви запитали. Звичайно, можу!


Додавання контенту за запитом


Іноді є сенс в тому, щоб надати користувачеві можливість завантажувати додаткову інформацію, а не відображати її на сторінці. Зазвичай розробники використовують прихований тег <div>, Що містить інформацію і відображає її за запитом користувача. У Rails є більш елегантна можливість, що використовує Ajax для отримання даних за запитом.


Лістинг 11 показує шаблон рецепта з доданим викликом допоміжного методу link_to_remote().


Лістинг 11. Search_ajax.rhtml





<% @recipes.each { /r/ %> <h1><%= r.name
%></h1> <p><%= r.description
%></p> <div id=”extra_<%= r.id
%>”></div> <%= link_to_remote
“Extra”, :url => { :action =>
“get_extra_ajax”, :id => r.id }, :update =>
“extra_#{r.id}” %> <% } %>

Метод link_to_remote() додає на сторінку код JavaScript разом з тегом-якорем (<a>), Що містить заданий текст. Коли користувач натискає на посилання, сторінка створює запит Ajax для отримання нового вмісту і заміняє їм текст в якорі.


Для отримання більшої кількості інформації я додаю ще один метод в RecipesControllerget_extra_ajax(). Цей метод показаний в лістингу 12.


Лістинг 12. Recipes_controller.rb





class RecipesController < ApplicationController … def get_extra_ajax
@recipe = Recipe.find( params[:id] ) render :layout=>false end end

І поряд з цим мені потрібен шаблон для додаткової інформації, званий get_extra_ajax.rhtml. Лістинг 13 показує цей шаблон.


Лістинг 13. Get_extra_ajax.rhtml





<blockquote><%= simple_format @recipe.ingredients
%></blockquote> <p><%= simple_format
@recipe.instructions %></p>

І тепер, заходячи на сторінку і набираючи apple в поле пошуку, я бачу щось схоже на рисунок 3.


Рисунок 3. Посилання на додаткову інформацію, що включає в себе інгрідієнти та інструкції
посилання на додаткову інформацію

Тепер, коли я натискаю на посилання, браузер використовує Ajax для отримання додаткового матеріалу з Web-сервера і його відображення. Ви можете побачити цей процес на малюнку 4.


Рисунок 4. Додаткова інформація про рецепти
Додаткова інформація про рецепти

Такий шаблон використання Ajax особливо зручний, коли ви маєте справу зі рядковими даними або деталізованим звітом, в яких пошук додаткової інформації по кожному записі вимагає великих витрат, отже, має сенс робити це лише на вимогу. Плюс ця техніка економить місце на екрані.


Можливо, найгарячішою можливістю Web 2.0 є текстові поля з автозаповненням. Яке ж розгляд Ajax буде повним без одного з них?


Поля з автозаповненням


Rails робить створення полів з автозаповненням до смішного простим. По-перше, я додаю нові елементи в шаблон index.rhtml. Оновлена ​​версія показана лістингу 14.


Лістинг 14. Оновлення index.rhtml





<html> <head> <%= javascript_include_tag
:defaults %> <style> div.auto_complete { width: 300px;
background: #fff; } div.auto_complete ul { border: 1px solid #888; margin: 0px;
padding: 0px; width: 100%; list-style-type: none; } div.auto_complete ul li {
margin: 0px; padding: 3px; } div.auto_complete ul li.selected { background-color:
#ffb; } div.auto_complete ul strong.highlight { color: #800; margin: 0px; padding:
0px; } </style> </head> <body> <%=
form_tag nil, { :id => “search_form” } %>
<p><%= text_field “recipe”,
“name”, :autocomplete => “off”
%></p> <div class=”auto_complete”
id=”recipe_name_auto_complete”></div>
<%= auto_complete_field :recipe_name, :url => {
:action=>”autocomplete_recipe_name” }, :tokens =>
“,” %> <%= end_form_tag %> …

Блок каскадних стилів (CSS) на початку файлу використовується для створення списку, що випадає автозаполняемих елементів. Після цього я зробив маленьке додавання в text_field для виключення автозаповнення в браузерах. Ще додав <div> для зберігання інформації для випадаючих списків і виклик методу auto_complete(). Допоміжний метод auto_complete() створює клієнтський код JavaScript, який викликає з сервера метод autocomplete_recipe_name() з поточним вмістом текстового поля recipe name в якості аргументу.


Метод autocomplete_recipe_name() в RecipesController запускає пошук по імені, як показано в лістингу 15.


Лістинг 15. Recipes_controller.rb





class RecipesController < ApplicationController … def
autocomplete_recipe_name @recipes = Recipe.find( :all, :conditions => [
“name LIKE ?”, “%#{params[:recipe][:name]}%” ] )
render :layout=>false end end

Цьому коду для побудови списку потрібно ще один шаблон ERB, як показано в лістингу 16.


Лістинг 16. Autocomplete_recipe_list.rb




                 <ul
class=”autocomplete_list”> <% @recipes.each { /r/
%> <li class=”autocomplete_item”><%=
r.name %></li> <% } %> </ul>

Система автозаповнення шукає список HTML (<ul>), В якому кожен елемент являє собою одну опцію. Їх форматує CSS на сторінці index.rhtml (або зазначений вами лист стилів).


Щоб побачити систему автозаповнення в дії, в браузері я переходжу на сторінку і набираю test. Для того щоб були деякі дані, я вводжу кілька тестових рецептів. Ви можете побачити результат на малюнку 5.


Рисунок 5. Випадаючий список автозаповнення
Випадаючий список автозаповнення

Я можу використовувати стрілки “вгору” і “вниз” для вибору елементу і кнопку “вхід” для підтвердження вибору. Обраний елемент міститься в текстове поле.


Це швидке рішення і – завдяки архітектурі Rails – легко здійсненне.


Вердикт


Я не посоромлюся сказати: “Я люблю Rails!” Звичайно, я спотикався, починаючи його використовувати. Наскільки я бачив в мережі, спотикалися більшість розробників. А чому б і ні? Rails дозволяє з неймовірною легкістю будувати високоінтерактівние Web-додатки.


Навіть якщо ви не збираєтеся купувати додаток Rails, я б порекомендував вам завантажити Instant Rails або Locomotive і випробувати їх. Вам сподобається – і ви дізнаєтеся багато про що такому, що могли б використовувати у своїх програмах на Java PHP або Microsoft. NET. Може навіть трапитися так, що ви захочете повністю перейти на Rails.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*