2012-07-02 3 views
10

Ho un modello spina dorsale come questoModello di partial in underscore (proprio come nel manubrio)?

var PeopleModel = Backbone.Model.extend({ 
defaults: {    
    "people": [ 
      { "username": "alan", "firstName": "Alan", "lastName": "Johnson", "phone": "1111", "email": "[email protected]" }, 
      { "username": "allison", firstName: "Allison", "lastName": "House", "phone": "2222", "email": "[email protected]" }, 
      { "username": "ryan", "firstName": "Ryan", "lastName": "Carson", "phone": "3333", "email": "[email protected]" }, 
      { "username": "ed", "firstName": "Edward", "lastName": "Feild", "phone": "4444", "email": "[email protected]" }, 
      { "username": "phil", "firstName": "Philip", "lastName": "Doom", "phone": "5555", "email": "[email protected]" }, 
      { "username": "gerald", "firstName": "Gerald", "lastName": "Butler", "phone": "6666", "email": "[email protected]" } 
    ], 
    "company": {"name": "Random Corp."}, 
    "country": "England" 
} 

}); 

E sotto sono i miei modelli

<script id="people-template" type="text/x-handlebars-template"> 
{{#each people}} 
    {{> person}} 
{{/each}} 
</script> 

<script id="person-partial" type="text/x-handlebars-template"> 
<div class="person"> 
    <h2>{{fullName}} </h2> 
    <div class="phone">{{phone}}</div> 
    <div class="email"><a href="mailto:{{email}}">{{email}}</a></div>  
</div> 

Ecco come ho implementato parziali utilizzando handlebars.js.

Le mie domande

1.Do ci hanno cosa simile, intendo i parziali in caso di motore di template underscore.js?

2. Se sì, come si fa a implementare parziale underscore.js template engine

risposta

16

No, non v'è alcun supporto nativo parziale nei modelli di sottolineatura. Ma puoi inserire praticamente tutti i JavaScript che desideri all'interno di <% ... %>; in particolare, puoi chiamare le tue funzioni in modo da poter aggiungere qualcosa di parzial-ish senza troppe difficoltà. Si potrebbe avere un modello come questo:

<script id="people-template" type="text/x-handlebars-template"> 
    <% _(people).each(function(person) { %> 
     <%= partial('person', person) %> 
    <% }) %> 
</script> 

e quindi aggiungere un partial funzione per window:

window.partial = function(which, data) { 
    var tmpl = $('#' + which + '-partial').html(); 
    return _.template(tmpl)(data); 
}; 

Demo: http://jsfiddle.net/ambiguous/HDuj5/9/

Questo non è così liscia e bella come {{> ... }} in Manubrio ma I template di Underscore sono un involucro molto sottile attorno a JavaScript e questo ti limita un po '. Puoi utilizzare gli spazi dei nomi per evitare di mettere le cose direttamente nello window oppure puoi usare lo {variable: ...} option to _.template e un wrapper per configurare i tuoi aiutanti standard.

+0

Grazie per aver pazientemente rispondere alla mia domanda, il tuo violino ha aiutato molto. Ho completamente dimenticato di usare "window" per questo caso. Thnks again – bhargav

+1

Attenzione che la versione a due argomenti di '_.template()' con i dati come il secondo argomento è stato deprecato dalla versione 1.7. L'approccio è ancora valido, però. –

+0

@ PeterV.Mørch: Grazie per il promemoria. Ho effettivamente risposto ad alcuni "perché non' _.template (tmpl, data) 'funziona?" domande di recente. –

13

O, per evitare l'uso di portata globale è possibile mescolare in aiutanti template globali in questo modo:

(function() { 
    var originalUnderscoreTemplateFunction = _.template; 
    var templateHelpers = {}; 

    _.mixin({ 
     addTemplateHelpers : function(newHelpers) { 
      _.extend(templateHelpers, newHelpers); 
     }, 

     template : function(text, data, settings) { 
      // replace the built in _.template function with one that supports the addTemplateHelpers 
      // function above. Basically the combo of the addTemplateHelpers function and this new 
      // template function allows us to mix in global "helpers" to the data objects passed 
      // to all our templates when they render. This replacement template function just wraps 
      // the original _.template function, so it sould be pretty break-resistent moving forward. 

      if(data) 
      { 
       // if data is supplied, the original _.template function just returns the raw value of the 
       // render function (the final rentered html/text). So in this case we just extend 
       // the data param with our templateHelpers and return raw value as well. 

       _.defaults(data, templateHelpers); // extend data with our helper functions 
       return originalUnderscoreTemplateFunction.apply(this, arguments); // pass the buck to the original _.template function 
      } 

      var template = originalUnderscoreTemplateFunction.apply(this, arguments); 

      var wrappedTemplate = function(data) { 
       _.defaults(data, templateHelpers); 
       return template.apply(this, arguments); 
      }; 

      return wrappedTemplate; 
     } 
    } 
} 

Quindi chiamare

_.addTemplateHelpers({ 
    partial : function() { 
     return _.template(
      $('#' + which + '-partial').html(), 
      data 
     ); 
    } 
}); 

Ecco un link al underscore mixin su GitHub.

+0

Si potrebbe fare qualcosa con _.partial e _.template per raggiungere questo obiettivo? – backdesk

+0

_.partial non è correlato al modello parziali: riempie gli argomenti nelle funzioni. – Dtipson

1

Penso che questo è simile alla risposta di Dave, ma forse richiede meno codice:

function partialTemplate(origTemplate, partialValues){ 
    return function(values){ 
     return origTemplate(_.defaults(values, partialValues)); 
    }; 
} 

Esempio utilizzo:

var t = _.template('<%= val1 %>,<%= val2 %>'); // original template requiring 2 values 
var pt = partialTemplate(t, {val1:1}); // partial template with 1 value pre-populated 
pt({val2:2}); // returns '1,2' 
pt({val2:3}); // returns '1,3'