Partials template in underscore (just like in handlebars)?

前端 未结 3 1879
囚心锁ツ
囚心锁ツ 2021-01-02 05:03

I have a backbone model like this

var PeopleModel = Backbone.Model.extend({
defaults: {              
    \"people\": [
          { \"username\": \"alan\", \         


        
相关标签:
3条回答
  • 2021-01-02 05:23

    Or to avoid using global scope you can mix in global template helpers like so:

    (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;
            }
        }
    }
    

    Then call

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

    Here is a link to the underscore mixin on github.

    0 讨论(0)
  • 2021-01-02 05:28

    No, there is no native partial support in Underscore's templates. But, you can put pretty much any JavaScript you want inside <% ... %>; in particular, you can call your own functions so you can add something partial-ish without much difficulty. You could have a template like this:

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

    and then add a partial function to window:

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

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

    That's not quite as slick and pretty as {{> ... }} in Handlebars but Underscore's templates are a very thin wrapper around JavaScript itself and that limits you somewhat. You can use namespaces to avoid putting things directly in window or you could use the {variable: ...} option to _.template and a wrapper to set up your standard helpers.

    0 讨论(0)
  • 2021-01-02 05:32

    I think this is similar to Dave's answer, but perhaps requiring less code:

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

    Example usage:

    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'
    
    0 讨论(0)
提交回复
热议问题