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

Реализация оперативного просмотра

Время на прочтение4 мин
Количество просмотров472
Проблема
Хотелось бы дать пользователям возможность оперативного просмотра данных в процессе редактирования, чтобы не получалось так, что после отправки из фор­мы данные появились в испорченном формате (когда речь идет, к примеру, о дневниковой записи, которую собираются выставить на всеобщее обозрение).


Решение
Оперативный просмотр легко осуществить с помощью встроенных в Rails по­мощников JavaScript. Для данного рецепта мы обойдемся созданием оперативно­го просмотра простейшей формы, предназначенной для создания дневниковой записи.
Первым делом при создании любого Rails-эффекта, связанного с использова­нием Ajax, нужно обеспечить включение в код нужных JavaScript-библиотек. Для достижения эффекта оперативного просмотра требуется включить лишь одну библиотеку — Prototype. Я рекомендую сделать это в главном шаблоне приложе­ния (в нашем случае — в файле layouts/standard.rhtml):

<html>
<head>
<%= javascript_include_tag «prototype» %>
</head>
<body>

</body>
</html>
* This source code was highlighted with Source Code Highlighter.

Теперь, обеспечив загрузку требуемых JavaScript-библиотек, нужно создать модель и контроллер, которые будут поддерживать ввод дневниковых записей. Мы будем вызывать класс модели Entry, передавая ему свойства title и body. Если хотите продолжать работу, не определяя соответствующей таблицы Active Record, то файл app/models/entry.rb должен приобрести следующий вид:

class Entry
attr_accessor :title, :body
end
* This source code was highlighted with Source Code Highlighter.


Контроллер будет называться DiaryController. Мы создадим его в файле app/control-lers/diary_controller.rb. Давайте придерживаться основ, и назовем действие по созда­нию новой записи new( ):

def new
entry = Entry.new
end
* This source code was highlighted with Source Code Highlighter.


Теперь настал черед самой функции. В представлении, созданном для этого действия, и будет твориться все наше волшебство. Создайте файл app/views/diary/new.rhtml и придайте ему следующий вид:

<% form_tag ({:action => «save»}, :id=> «entry-form») do %>
<%= text_field :entry, :title %> <br />
<%= text_area :entry, :body %> <br />
<%= submit_tag «Save» %>
<% end -%>

<%= observe_form «entry-form»,
:frequency=>2,
:update=>«live-preview»,
:complete=>«Element.show('live-preview')»,
:url=> {:action => «preview»} %>

<div id=«live-preview» style=«display:none; border:1px solid»></div>
* This source code was highlighted with Source Code Highlighter.


Мы создали стандартную, универсальную форму с id, имеющим значение entry-form, поэтому на нее можно ссылаться из всего остального кода. За опреде­лением формы следует вызов помощника observe_form( ), который генерирует тре­буемый JavaScript-код для опроса каждого элемента формы, выведенной на стра­нице (ссылаясь на нее по id), и поиска изменений. Опрос будет вестись через интервалы времени (в секундах), заданные параметром frequency. Как только бу­дут замечены изменения, на URL, определенный параметром :url, будет направлен вызов, которому в качестве параметров будут переданы данные формы. Параметр :update определяет HTML-элемент (опять же по его id), который будет обновлен результатами URL-вызова. В данном случае содержимое элемента , который используется для оперативного просмотра, будет обновлено тем, что в конечном счете будет отправлено в результате вызова действия preview( ).
Чтобы сделать элемент оперативного просмотра невидимым при первоначаль­ной загрузке страницы, мы воспользовались встроенным CSS. Пока пользователь не введет какие-либо данные, в элементе оперативного просмотра нечего будет показывать. Параметр :complete, передаваемый помощнику observe_form( ), предписы­вает после завершения вызова действия preview( ) выполнение фрагмента Java­Script, который включит отображение элемента оперативного просмотра.
Если в оперативном просмотре нужно отобразить всего лишь одно поле, то мы можем взамен воспользоваться помощником observe_field( ).
Теперь осталось только обеспечить выполнение действия preview( ). Вот его код, взятый из контроллера:

def preview
render :layout => false
end
* This source code was highlighted with Source Code Highlighter.


Единственная задача, выполняемая кодом действия, — это «закорачивание» обычной схемы отправки данных, используемой в приложении. Поскольку мы собираемся обновлять элемент оперативного просмотра на странице создания еже­дневных дневниковых записей и использовать для этого лишь результаты, воз­вращаемые действием preview( ), возвращать целиком всю HTML-страницу не тре­буется. Нам нужен лишь отрывок, имеющий определенный смысл в составе более объемного содержимого экрана.
Представление, предназначенное для действия preview( ), находится в файле app/views/diary/preview.rhtml и должно иметь следующий вид:

<h2>Preview:</h2><br />
<h3><%= params[:entry][:title] %></h3>
<%= textilize params[:entry][:body] %>
* This source code was highlighted with Source Code Highlighter.


Вот и все! Это представление использует HTML-заголовок для названия за­писи, а затем, используя метод textilize( ), генерирует HTML-выход. Внутри этого метода используется библиотека RedCloth для преобразования простой тексто­вой разметки в HTML.
Теперь можно загрузить форму ввода дневниковой записи и посмотреть, как обычный текст преобразуется в HTML еще до того, как будет сделан щелчок на кнопке Save.


P.S.
Параметру frequency, использующемуся в методах observe_field( ) и observe_form( ), можно присвоить нулевое или отрицательное значение, что приведет к обзору по­ля в реальном масштабе времени. Казалось бы, что может быть плохого в мгно­венной реакции пользовательского интерфейса, но на самом деле она будет по­давлена, не говоря уже о дополнительной тяжелой нагрузке на серверы. При отслеживании изменений в реальном масштабе времени каждое изменение вызо­вет отправку запроса на сервер, от которого нужно дождаться результата, чтобы увидеть обновление на экране. Изменения становятся в очередь, в результате че­го обновления оперативного просмотра медленно следуют за ними, ожидая оче­редного перехвата.

Кросспост из моего блога

P.S.
Да, пожалуйста, если Вам что то не понятно — напишите в коментах. Хватит минусовать карму за топики, которые вроди бы (ИМХО) несут полезную информацию.
Теги:
Хабы:
+7
Комментарии5

Публикации

Истории

Работа

Программист Ruby
8 вакансий
Ruby on Rails
10 вакансий

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн