Добавляем jQuery в Grails
Собственно никаких проблем с AJAX в Grails не наблюдается: контроллеры могут спокойно возвращать JSON-данные, GSP-страницы могут использовать соответствующие вспомогательные тэги.
По умолчанию Grails дружит с Prototype JS. Однако можно легким движением руки установить плагин поддержки jQuery.
grails install-plugin jquery
Будет установлен jQuery 1.4.x. Далее нам необходимо объявить jQuery как «JavaScript provider» в Grails. В этом случае все встроенные тэги Grails начнут работать через jQuery.
Добавляем в grails-app/Config.groovy строчку:
grails.views.javascript.library="jquery"
Поскольку мы хотим, чтобы все страницы нашего приложения начали использовать jQuery, сразу добавим в основной layout-файл (по умолчанию это grails-app/views/layouts/main.gsp) в секцию HEAD:
<html> <head> ... <g:javascript library="jquery"/> ... </head> ... </html>
Теперь на каждой странице приложения будет автоматически подгружаться jQuery.
Пишем что-нибудь на jQuery
У нас уже заработали такие, например, конструкции:
<div id="ajaxContainer">Nothing here.</div> <g:remoteLink action="show" id="1" update="ajaxContainer">Обновить!</g:remoteLink>
Если посмотреть это в runtime, то будет видно, что неявно используется функция jQuery.ajax().
Заглянув в web-app/js/application.js, обнаруживаем, что сгенерированный (с помощью
grails create-app
) код AJAX-индикатора написан для Prototype. Встроенная индикация выглядит криво (на мой вкус), но если очень хочется, чтобы она заработала, можно переписать код на jQuery:jQuery(document).ready(function() { jQuery(document).ajaxStart(function(){ $('#spinner').show(); }); jQuery(document).ajaxStop(function(){ $('#spinner').fadeOut(500); }); });
Пишем контроллер
Напоследок напишем контроллер, пригодный для работы с AJAX. Например, вернем из контроллера случайное число в виде JSON:
def random = { def max = params.int('max') render(contentType:"text/json") { rnd = new Random().nextInt(max) } }
Здесь мы используем новый вариант JSON builder из Grails 1.2.x. Результатом работы контроллера будет JavaScript-массив вида
{rnd: 34}
, который мы можем использовать, например, так:<p> Случайное число: <input type="text" name="rnd" id="out" value="" /> <g:remoteLink action="random" params="[max:100]" onSuccess="\$('#out').val(data.rnd);">Генерировать!</g:remoteLink> </p>
Здесь из JSON-результата (который в нашем случае попадает в переменную
data
) выбирается значение rnd
и заносится в текстовое поле.В скобках замечу, что «прозрачность» замены одного JavaScript-провайдера на другого работает только до определенного момента. Как только вы выходите за пределы встроенных AJAX-тэгов Grails и начинаете использовать функции jQuery (как в примере выше), совместимость с другими провайдерами тут же теряется.