jsrender nested templates with string markup

2019-06-12 11:56发布

i'm newbie with jsrender. I've writting template for one custom treeview with script markup see above :

 <script id="jstemplate" type="text/x-jsrender">
        {{if IsFolder}}{{include tmpl="#jsfoldertemplate"/}}{{else}}{{include tmpl="#jsfiletemplate"/}}{{/if}}
</script>

<script id="jsfoldertemplate" type="text/x-jsrender">
    <li data-jstree='{"type":"{{:ClassName}}"}' data-fold="{{:IsFolder}}" data-path="{{:RP}}">{{:Nom}}&nbsp;<span style="font-size:smaller">({{:Size}}&nbsp;{{:NbFiles}}&nbsp;fichier(s))&nbsp<span>{{:Lock}}</span></span>
        <ul>
            {{for children tmpl="#jstemplate"/}}
        </ul>
    </li>
</script>

<script id="jsfiletemplate" type="text/x-jsrender">
    <li data-jstree='{"type":"{{:ClassName}}"}' data-fold="{{:IsFolder}}" data-path="{{:RP}}">
        <span {{:InspectorInfo}} class="SpanEtat {{:Inspector}}"></span>&nbsp;
        <span class="ui-link" onclick="$get('<%=Me.ClientID%>').FileSelected('{{:RP}}','{{:Nom}}');" style="vertical-align:middle">{{:Nom}}</span>&nbsp;
        <span style="font-size:smaller">({{:Size}}&nbsp;{{:LastModif}})&nbsp;<span>{{:Lock}}</span></span>
    </li>
</script>

And after in my js code :

$(#MyDiv').html('<ul>' + $('#jstemplate').render(NO.Nodes) + '</ul>');

that's work fine

Now i would like to put this template in a string (for writting an jqm widget) but i'm become crazy with subtemplate....

i've tried a lot of solution but nothing work....

if someone have any ideas ...?

thanks

标签: jsrender
1条回答
一纸荒年 Trace。
2楼-- · 2019-06-12 12:12

Before answering your question about compiling template from strings, here is a suggestion to simplify your "jstemplate":

Instead of

{{if IsFolder}}{{include tmpl="#jsfoldertemplate"/}}{{else}}{{include tmpl="#jsfiletemplate"/}}{{/if}}

you can write:

{{if IsFolder tmpl="#jsfoldertemplate"}}{{else tmpl="#jsfiletemplate"}}{{/if}}

For registering templates from strings, take a look at this page: http://www.jsviews.com/#d.templates. You'll see a section and a sample on "Registering multiple templates".

Following that pattern, you can register all three templates as named templates, from strings:

$.templates({
  jstemplate: '{{if IsFolder tmpl="jsfoldertemplate"}}{{else tmpl="jsfiletemplate"}}{{/if}}',
  jsfoldertemplate: '<li data-jstree=\'{"type":"{{:ClassName}}"}\' data-fold="{{:IsFolder}}" data-path="{{:RP}}">{{:Nom}}&nbsp;<span style="font-size:smaller">({{:Size}}&nbsp;{{:NbFiles}}&nbsp;fichier(s))&nbsp<span>{{:Lock}}</span></span>'
    + '<ul>{{for children tmpl="jstemplate"/}}</ul></li>',
  jsfiletemplate: '<li data-jstree=\'{"type":"{{:ClassName}}"}\' data-fold="{{:IsFolder}}" data-path="{{:RP}}">'
    + '<span {{:InspectorInfo}} class="SpanEtat {{:Inspector}}"></span>&nbsp;'
    + '<span class="ui-link" onclick="$get(\'<%=Me.ClientID%>\').FileSelected(\'{{:RP}}\',\'{{:Nom}}\');" style="vertical-align:middle">{{:Nom}}</span>&nbsp;'
    + '<span style="font-size:smaller">({{:Size}}&nbsp;{{:LastModif}})&nbsp;<span>{{:Lock}}</span></span></li>'
});

and then call:

$('#MyDiv').html('<ul>' + $.render.jstemplate(NO.Nodes) + '</ul>');

Alternatively, if you don't want to globally register the templates, you can register the second and third templates as sub-templates of the first, and the first one can be compiled as a template object, without registering it by name. In order to recursively call the first template from the sub-template, you can either register just the first one by name, and call it as {{for children tmpl="jstemplate"/}} or else just keep it as an object, but pass that jstemplate object in as a helper: jstemplate.render(NO.Nodes, {jstemplate: jstemplate}), and call it like this: {{for children tmpl=~jstemplate/}}

(See the same page: http://www.jsviews.com/#d.templates - the section on Associating private resources with templates.)

That gives you:

var jstemplate = $.templates({
      markup: '{{if IsFolder tmpl="jsfoldertemplate"}}{{else tmpl="jsfiletemplate"}}{{/if}}',
      templates: {
        jsfoldertemplate: '<li data-jstree=\'{"type":"{{:ClassName}}"}\' data-fold="{{:IsFolder}}" data-path="{{:RP}}">{{:Nom}}&nbsp;<span style="font-size:smaller">({{:Size}}&nbsp;{{:NbFiles}}&nbsp;fichier(s))&nbsp<span>{{:Lock}}</span></span>'
          + '<ul>{{for children tmpl=~jstemplate/}}</ul></li>',
        jsfiletemplate: '<li data-jstree=\'{"type":"{{:ClassName}}"}\' data-fold="{{:IsFolder}}" data-path="{{:RP}}">'
          + '<span {{:InspectorInfo}} class="SpanEtat {{:Inspector}}"></span>&nbsp;'
          + '<span class="ui-link" onclick="$get(\'<%=Me.ClientID%>\').FileSelected(\'{{:RP}}\',\'{{:Nom}}\');" style="vertical-align:middle">{{:Nom}}</span>&nbsp;'
          + '<span style="font-size:smaller">({{:Size}}&nbsp;{{:LastModif}})&nbsp;<span>{{:Lock}}</span></span></li>'
  }
})

$('#MyDiv').html('<ul>' + jstemplate.render(NO.Nodes, {jstemplate: jstemplate}) + '</ul>');

And here is another variant - where I have simplified the templates to make it easier to show the relationship between the templates and the recursive calling of the initial template. Here the initial template is being provided to sub-templates for a recursive call as a template parameter: ~toptmpl=#tmpl which is then be called using {{for children tmpl=~toptmpl/}}:

var jstemplate = $.templates({
      markup: '{{if IsFolder tmpl="jsfoldertemplate" ~toptmpl=#tmpl}}{{else tmpl="jsfiletemplate"}}{{/if}}',
      templates: {
        jsfoldertemplate: '<li>{{:Nom}} fichiers<ul>{{for children tmpl=~toptmpl/}}</ul></li>',
        jsfiletemplate: '<li>{{:Nom}}</li>',
      }
    });

$('#MyDiv').html('<ul>' + jstemplate.render(NO.Nodes) + '</ul>');
查看更多
登录 后发表回答