По сути, есть два места для определения функций JavaScript в Grails: непосредственно в элементе GSP и в отдельном исходном файле javascript в / web-app / js (например, application.js). Мы определили часто используемую повторно функцию javascript в application.js, но нам также необходимо иметь возможность динамически генерировать части функции, используя отличный код. К сожалению, $ {some groovy code}, похоже, не обрабатывается в отдельных исходных файлах javascript.
Единственный способ сделать это - определить функцию javascript в теге скрипта на странице GSP, или есть более общее решение? Очевидно, мы могли бы определить функцию javascript в теге сценария в файле GSP шаблона, который будет использоваться повторно, но требуется много усилий, чтобы все наши функции javascript были определены вместе в одном месте (то есть во внешнем исходном файле javascript). Это также дает преимущества в производительности (исходные файлы javascript обычно просто загружаются один раз браузером каждого клиента, вместо того, чтобы перезагружать те же функции javascript в источнике каждой посещаемой ими html-страницы). Я играл с идеей разбить функцию на статические и динамические части, поместить статические во внешний источник и поместить динамические в шаблон GSP, а затем склеить их вместе, но это похоже на ненужный взлом.
Любые идеи?
(edit: Может показаться, что идея динамически генерировать части функции JavaScript, которая затем загружается один раз и используется снова и снова клиентом, была бы плохой идеей. Однако часть, которая является «динамической», изменяется только возможно, раз в неделю или месяц, а затем совсем немного. В основном мы просто хотим, чтобы этот фрагмент был сгенерирован из базы данных, даже если только один раз, а не жестко закодирован.)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Простое решение сделать ваш JavaScript ненавязчивым - создать JavaScriptController и сопоставить его действия "/ js / *", добавив это в ваш файл UrlMappings.groovy:
"/js/$action"{
controller = "javascript"
}
затем просто создайте действие для каждого динамического JS-файла, который вы хотите, включите в свой макет <HEAD>, и готово, у вас есть JS-файл, в который вы можете вставлять фрагменты Grails! :)
Примечание: Я обнаружил, что в настоящее время в Grails есть ошибка, из-за которой расширения файлов не сопоставляются с типами содержимого должным образом, поэтому вам нужно включить <%@ page contentType = "text/javascript; UTF-8" %> в начало файлов просмотра.
Есть другой способ - передать сгенерированный код в функцию, ожидающую закрытия. Эти замыкания, конечно же, генерируются программой. Сгенерированный код, конечно, встроен / помечен тегами сценария на странице gsp.
он может работать или не работать в зависимости от характера генерируемого кода. Но я подозреваю, что это сработает, и если это не так, небольшая настройка стиля кодирования вашего javascript определенно заставит его работать. Хотя, если этот «сгенерированный» код не сильно меняет, imo, это перебор.
Или у этого ... есть тег / служба / динамический метод, который позволяет тегам записывать свои JS + CSS + все, что угодно, в «кеш», который используется для создания ресурсов JS + CSS другим контроллером.
Полная концепция здесь: [http://www.anyware.co.uk/2005/2009/01/19/an-idea-to-give-grails-tags-esp/ visible[1]
Это отличное решение. Я хотел бы предложить использовать что-нибудь кроме отображения
"/js/$action"because this is no longer going to allow you to access you javascript files in /web-app/js/. All your javascript files would have to be moved to a the directory your controller would point to.
Я бы использовал что-то вроде
"/dynjs/$action"
Таким образом, вы по-прежнему можете указывать на файлы в / web-app / js / files без конфликтов и пользоваться преимуществами тегов gsp в файлах javascript.
Пожалуйста, поправьте меня, если я ошибаюсь.
Я бы добавил это как комментарий, но моя репутация в настоящее время ниже 50, поэтому я не могу комментировать ответы других людей.
Хорошая точка зрения. Однако имейте в виду, что вам не нужно создавать полное сопоставление URL-адресов для «/ js / $ action», и вы можете напрямую указывать одно действие, то есть «/js/dyn.js».
Если вы хотите использовать модели, созданные контроллером (это отображаемая HTML-страница, которая ссылается на Javascript, в котором вы собираетесь использовать отличный код) в коде Javascript, вы можете использовать этот метод:
Этот метод не требует изменения сопоставлений URL-адресов и не требует создания дополнительного контроллера.
На ваш взгляд, GSP добавляет JavaScript следующим образом:
<script type = "text/javascript">
<g:render template = "/javascript/yourJavascriptFile"/>
</script>
В папке просмотров создайте папку "javascript". И создайте файл с именем: _yourJavascriptFile.gsp
Вы можете не только использовать весь код GSP в вашем файле _yourJavascriptFile.gsp, но также можете использовать все модели, созданные в вашем контроллере (т. Е. Рендеринг представления).
ПРИМЕЧАНИЕ. В папке javascript нет ничего особенного. Вы можете назвать его как хотите ИЛИ использовать существующую папку просмотра. Это всего лишь вопрос организации и идентификации вашего GSP, воспроизводящего HTML, из GSP, воспроизводящего Javascript. В качестве альтернативы вы можете использовать некоторые соглашения об именах, например: _something.js.gsp и т. д.
Назовите свои скрипты так
/wherever/the/js/files/are/thescript.js.gsp
Код gsp внутри будет правильно отображаться с помощью grails. Это работает, но я понятия не имею, считается ли это хорошей идеей или нет.
Добро пожаловать! На прошлой неделе я столкнулся с похожей проблемой, за исключением того, что имел дело с файлами CSS :)