2010-11-17 1 views
8

В настоящее время я реорганизую игру! проект, в котором много файлов JS в файлах шаблонов HTML. Этот код должен быть перемещен на внешние файлы JS для лучшей читаемости и более быстрого времени загрузки страницы. Тем не менее, , когда я просто создаю файл JS в общей папке, все замены ссылок @ {Controller.method} больше не работают. Я думать о вызове некоторой функции инициализации из HTML шаблонов, которые просто поставляют необходимые URL-адрес, какИграйте! Рамка: Лучшая практика использования URL-адресов в отдельных файлах JavaScript?

initialize({ "Application.doThis" : "@{Application.doThis}"}) 

однако это становится очень громоздким и подвержены ошибками с любой URL , который добавляется. Другое дело, что I18N также больше не работает. Итак, Какова наилучшая практика для таких сценариев, где у вас есть код JS в отдельном файле, но все же хотите использовать создание URL-адреса и I18N в вашем JS?

ответ

12

В главном шаблоне, генерировать 'JavaScript маршрутизатор', что-то вроде:

<script> 
    var routes = { 
     doThis: #{jsAction @Application.doThis(user, ':param1', ':param2') /}, 
     doThat: #{jsAction @doThat() /} 
    } 
</script> 

А потом в какой-либо 'статический' JavaScript-файл, используйте этот маршрутизатор:

$.get(routes.doThis({param1: x, param2: 'yop'})) 
+1

спасибо. Это было то, что я имел в виду, однако на самом деле это означает, что у меня есть много кода шаблона, который я должен распространять каждый раз, когда появляется новый маршрут, который легко забывается. Другое дело - использовать i18n для сообщений внутри JavaScript, можно, конечно, написать такой «роутер» для сообщений, но это эффективно дублирует все ключи I18N в JavaScript. –

+0

Вы уже можете использовать тег # {18n /}. Я думаю, мы могли бы предоставить тег, который выставляет весь файл маршрута через javascript, но это может привести к проблемам безопасности. –

+0

Хорошо, спасибо вам большое! –

5

Хитрость заключается в том чтобы получить структуру для анализа вашего javascript, или вашего CSS, или что-либо еще в статических каталогах. Вот простое решение.

Добавить controllers.StaticParser контроллер:

package controllers; 
import play.mvc.Controller; 

public class StaticParser extends Controller { 
    public static void parse(String route) { 
     render("/" + route); 
    } 
} 

К вашему conf/routes файл дополнения:

GET /parse/{<.*>route} StaticParser.parse 

Регулярное выражение в том, что маршрут очень важно, в противном случае вы не можете добавить Pathing к запросу. Чтобы запросить разобранный статический ресурс, такие как JS скрипт, используйте:

<script src="/parse/public/javascripts/test.js" 
    language="javascript" type="text/javascript" ></script> 

К сожалению, вы не можете использовать формат #{script 'test.js' /}, поскольку тег сценария выглядит для статического файла. Чтобы исправить эту досаду, вот бесстыдный взлом тега скрипта: тег #{parsescript 'test.js'/}. Он должен пойти в /views/tags/parsescript.tag:

{ 
* insert a parsescript tag in the template. 
* by convention, referred script must be put under /public/javascripts 
* src  (required) : script filename, without the leading path "/public/javascripts" 
* id  (opt.)  : sets script id attribute 
* charset (opt.)  : sets source encoding - defaults to current response encoding 
* 
* #{parsescript id:'datepicker' , src:'ui/ui.datepicker.js', charset:'${_response_encoding}' /} 
}* 
%{ 
    (_arg) && (_src = _arg); 

    if (!_src) { 
     throw new play.exceptions.TagInternalException("src attribute cannot be empty for script tag"); 
    } 
    _src = "/public/javascripts/" + _src 
    try { 
     _abs = play.mvc.Router.reverseWithCheck(_src, play.Play.getVirtualFile(_src), false); 
    } catch (Exception ex) { 
     throw new play.exceptions.TagInternalException("File not found: " + _src); 
    } 
}% 
<script type="text/javascript" language="javascript"#{if _id} id="${_id}"#{/if}#{if _charset} charset="${_charset}"#{/if} src="/parse${_abs}"></script> 

Это работает точно так же, как #{script /} тега, но разбирает файл перед его возвращением: #{parsescript 'test.js' /}

Можно было бы столь же бесстыдно взломать #{stylesheet /} тег, но я думаю, что я принял уже достаточно пространства.


Смежные вопросы