Toque! Framework: Melhores práticas para usar URLs em arquivos JavaScript separados?
-
25-09-2019 - |
Pergunta
Atualmente, estou reorganizando uma peça! Projeto onde há muitos código JS nos arquivos de modelo HTML. Este código deve ser movido para arquivos JS externos para obter melhor legibilidade e tempos de carregamento de página mais rápidos. No entanto, quando eu apenas crio um arquivo JS na pasta pública, todas as substituições de link @{controller.method} não estão mais funcionando. Eu estava pensando em chamar uma função de inicialização dos modelos HTML que apenas fornecem os URLs necessários como
initialize({ "Application.doThis" : "@{Application.doThis}"})
No entanto, isso está se tornando muito pesado e propenso a erros com qualquer URL adicionado. Outra coisa é que o i18n também não funciona mais. Então, qual é a melhor prática para cenários como esses, onde você tem seu código JS em um arquivo separado, mas ainda deseja usar a geração de URL e o i18n em seu JS?
Solução
No modelo principal, gerar um 'roteador JavaScript', algo como:
<script>
var routes = {
doThis: #{jsAction @Application.doThis(user, ':param1', ':param2') /},
doThat: #{jsAction @doThat() /}
}
</script>
E então, em qualquer arquivo JavaScript 'estático', use este roteador:
$.get(routes.doThis({param1: x, param2: 'yop'}))
Outras dicas
O truque é obter a estrutura para analisar seu JavaScript, ou seu CSS, ou qualquer outra coisa nos diretórios estáticos. Aqui está uma solução fácil.
Adicione a controllers.StaticParser
controlador:
package controllers;
import play.mvc.Controller;
public class StaticParser extends Controller {
public static void parse(String route) {
render("/" + route);
}
}
Para o seu conf/routes
Adicionar arquivo:
GET /parse/{<.*>route} StaticParser.parse
O regexp nessa rota é muito importante; caso contrário, você não pode adicionar caminho à solicitação. Para solicitar um recurso estático analisado, como um script JS, use:
<script src="/parse/public/javascripts/test.js"
language="javascript" type="text/javascript" ></script>
Infelizmente, você não pode usar o #{script 'test.js' /}
Formato, porque a tag de script procura o arquivo estático. Para corrigir essa coisa irritante, aqui está um truque sem vergonha da etiqueta do script: o #{parsescript 'test.js'/}
marcação. Deve ir para /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>
Funciona exatamente como o #{script /}
Tag, mas analisa o arquivo antes de devolvê -lo: #{parsescript 'test.js' /}
Pode -se que pudesse hackear igualmente descaradamente o #{stylesheet /}
Tag, mas acho que já ocupei espaço suficiente.