Pergunta

Quero emitir alguns js de modelos jQuery, por exemplo, tenho um modelo como

<script id="tmplID" type="text/x-jQuery-tmpl">
<input id="static.${val}" type="text"/>
<input id = "static2.${val}" type="text"/>
<script type="text/javascript">
$('#static.'+${val}).change(function(){
  alert('some value');
});
</script>
</script>  

Quando eu chamo este modelo, como:

var obj = {val:'123'};
$('#tmplID').tmpl(obj).appendTo("some_container");

ele renderiza a função de alteração do JavaScript como string na página, enquanto eu quero que seja anexado como JavaScript executável.

Foi útil?

Solução

Existem vários problemas com o seu código.

Primeiro de tudo, você nunca deve usar tags <script> aninhadas. Mesmo que a tag de fechamento </script> esteja dentro de uma string em um bloco de javascript, você ainda deve dividi-la para que não apareça como está, já que pode desarmar até mesmo a maioria dos navegadores compatíveis com os padrões. Sem mencionar os mais velhos ...

Da mesma forma, você deve evitar o uso de pontos em IDs, pois é muito fácil ignorar ao escrever seus seletores jQuery. #id.something significa "selecione o elemento com o id id que também possui a classe something aplicada a ele" . Se você não consegue viver sem ele, pode escapar dele ao escrever seu seletor como #id\\.something, que "selecionará o elemento com o id id.something" .

Também é uma má ideia colocar javascript dentro do seu modelo, você deve repensar o que está tentando alcançar. Quase sempre há uma maneira de contornar isso:

  • Você pode vincular seus eventos com .delegate() ou .live() para elementos que você só criará no futuro.

  • Em vez de codificar o ID no script, você pode usar diferentes seletores, por exemplo, você pode aplicar uma classe exclusiva para usar com as ligações acima, de forma que não interfira na marcação existente. Se precisar do ID dentro do manipulador de eventos, você pode extraí-lo facilmente com this.id ou $(this).attr('id').

  • Se desejar personalizar 'some value' em seu script, você pode adicionar atributos personalizados a seus elementos, por exemplo, <input id="static_something" data-custom="some value" /> e extraia-o em sua função usando $(this).data('custom').

Levando todos os itens acima em consideração, eu reescreveria seu código para algo semelhante a este:

<script id="tmplID" type="text/x-jquery-tmpl">
<input id="static_${val}" class="templateinput" type="text" data-custom="value1" />
<input id="static2_${val}" class="templateinput" type="text" data-custom="value2" />
</script>

<script type="text/javascript">
// jQuery ready function
$(function(){
    $('.templateinput').live('change', function(){
        var element_id = this.id;
        var element_data = $(this).data('custom');

        alert('The value of input #' + element_id + ' is: ' + element_data);
    });
});
</script>

Se você tiver um contêiner conhecido que conterá todos os itens do seu modelo, use .delegate() para maior clareza e evitar vinculação global.

Outras dicas

Você não poderia simplesmente configurar o evento depois de renderizar o modelo?

var obj = {val:'123'};
$('#tmplID').tmpl(obj).appendTo("some_container");

$('#static.'+obj.val).change(function() {
    ...
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top