2010-02-14 14 views
5

Sto cercando di sviluppare un modo semplice per creare modelli in JavaScript. L'idea di base è che ho HTML in una pagina che rappresenta l'interfaccia utente di un oggetto in JavaScript e le variabili in quell'HTML che vengono sostituite con le proprietà dell'oggetto JavaScript. Pensala come una tecnica per il binding degli oggetti JavaScript alle presentazioni HTML.Migliorare una semplice tecnica di template JavaScript

Eventuali critiche? Dovrei usare in qualche modo frammenti di documenti? Sto essenzialmente cercando una recensione del codice su questo. Apprezzerei qualsiasi feedback. (Nota che questo dovrebbe essere indipendente dal framework.) Ecco un exmaple funzionante.

<html> 
<body> 

    <!-- where templates will be injected into --> 
    <div id="thumbContainer"></div> 

    <!-- template used for thumbnails --> 
    <div id="thumbTemplate" style="display:none"> 
     <div class="thumb"> 
      <div>${caption}</div> 
      <div>${image}</div> 
     </div> 
    </div> 

</body> 

<script type="text/javascript"> 
(function() { 

    // Cache the templates' markup in case that template is used again 

    var cache = []; 

    // Magic 

    document.templatized = function(templateId, properties) { 

     // Get the template from cache or get template and add to cache 

     var template = cache[templateId] || (function() { 
      cache[templateId] = document.getElementById(templateId).innerHTML; 
      return cache[templateId]; 
     })(); 

     // Create the DOM elements that represent the markup 

     var shell = document.createElement('div'); 

     shell.innerHTML = template.replace(/\$\{(\w+)\}/g, function(match, key){ 
      return properties[key] || match; 
     }); 

     // Return those DOM elements 

     return shell.children[0].cloneNode(true); 
    }; 
})(); 

// Create DOM elements with values bound to thumbnail object 

var thumb = document.templatized('thumbTemplate', { 
    caption: 'Summer', 
    image: (function() { 
      // More complicated logic that requires conditions here... 
     return '<img src="test.png" />'; 
    })() 
}); 

// Display on page by inserting into DOM 

document.getElementById('thumbContainer').appendChild(thumb); 
</script> 
+0

+1 per // magic – cherouvim

+0

Haha, grazie! :) La caratteristica di codifica – JamesBrownIsDead

risposta

2

Il codice è pulito.

Avrei il modello in un commento html quindi 1) non viene visualizzato (non è necessario per il display: nessuno hack) e 2) Sarei in grado di avere cose che non convalidano, tali come diretto a <tr>.

Inoltre, rimuoverei la creazione "div" codificata in modo da poter supportare snippet di modello che iniziano con qualsiasi elemento html.

In seguito aggiungerei la navigazione del grafico (ad esempio $ {foo.bar}), l'iterazione e le istruzioni if.

2

+1 cherouvim: stai usando il modello come testo, quindi tienilo come testo. Puoi passarlo al tuo script come commento, oppure puoi passarlo come stringa con codifica JSON, ma usare il markup è potenzialmente pericoloso.

Ad esempio:

<form method="${mymethod}"><table> 
    <tr><td> 
     <${mylisttype}> 
      <li> 
       <input name="foo" value="${myvalue}"> 
      </li> 
     </${mylisttype}> 
    </td></tr> 
    ${extrarow} 
</table></form> 

illustra alcune cose non si può fare in modo affidabile nella vostra lingua di template per effetto del browser 'fissare' la marcatura e la modifica della tornata innerHTML posteriore: il form può essere mutato a method="get" (o, in IE, omessa FSR); a meno che non si sia in modalità XML, verrà aggiunto un elemento <tbody>; l'elemento mutevole non funzionerà affatto; il testo ${extrarow} non è valido direttamente all'interno di una tabella; il input.value può essere mutato al caricamento della pagina mentre i browser tentano di reimpostare i valori del campo modulo e IE riflette in modo errato le modifiche del valore del campo come attributi/innerHTML.

Inoltre, vi consiglio vivamente l'aggiunta di una funzione di codifica HTML (sostituendo & con &amp;, < con &lt; e qualsiasi delimitatori valore di attributo con riferimenti simili). L'esperienza con i linguaggi dei modelli ha dimostrato che è molto più comune voler inserire una stringa di testo nel documento piuttosto che una porzione di markup. Quando si esegue:

Hello, ${name}! 

senza applicare sfuggire alla variabile name, si sta aprendo l'applicazione fino ad attacchi di cross-site scripting. I moderni linguaggi dei modelli evitano questo problema applicando la codifica HTML di default, perché i programmatori sono troppo pigri per farlo manualmente (se capiscono anche i problemi coinvolti). Questo è il motivo per cui la maggior parte delle app PHP è vulnerabile agli attacchi XSS.

Non portare lo stesso problema sul lato client; ne fanno sfuggire per impostazione predefinita, offrendo una bandiera per dire che non si vuole fuggire per le (di solito relativamente pochi) casi in cui si desidera inserire markup grezzo:

<div>${caption}</div> 
<div>${image|markup}</div> 
+1

sarebbe fantastica – cherouvim

1

Piuttosto che avere in un commento HTML è possibile metterlo nei tag, ad esempio:

<script type="text/html" id="mytemplate"> 
    ... template here ... 
</script> 

Il bello è che tutti i browser e tutti i robot correttamente scritte ignoreranno blocchi di script in cui non sa come interpretarli; e puoi facilmente accedere al contenuto tramite l'ID (come se fosse un div).

+0

Questo è il modo in cui funzionano diversi plug-in jQuery e la proposta di modelli di Microsoft. http://wiki.github.com/nje/jquery/jquery-templates-proposal – R0MANARMY

Problemi correlati