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?

Foi útil?

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.


Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top