jsRender is the in-development successor to jQuery Templates (jquery-tmpl). I’ve been playing around with it, and have struggled with a clean way to pass additional parameters to nested templates. What I’ve got so far:
<script id="t-parent" type="text/x-jquery-tmpl">
<h1>{{=section}}</h1>
<ul>
{{#each subsections}}
<li>{{=subsection}} in {{=$view.parent.parent.data.section}} AKA {{section_name}}</li>
{{/each}}
</ul>
</script>
And the relevant JavaScript, including the {{section_name}} template tag:
$.views.registerTags({
section_name: function() {
return this._view.parent.parent.data.section;
}
});
var o = { section: "Sample", subsections: [ { subsection: "Skydiving"}, { subsection: "Skiing"} ] };
$('#container').html($('#t-parent').render(o));
I’m questioning $view.parent.parent.data.section. Seems a bit verbose, but I can’t find a cleaner way to step out of the nested template and access variables from the outer scope.
I’ve posted a jsFiddle of the above.
Hi Adam, yes your syntax is correct, and there is also a slightly more compact syntax you can use: {{=$parent.parent.data.section}}. The idea is that $foo maps to $view.foo, by default, and from $view, you can basically get to any view in the view tree, and from a view get to data properties, indices, templates, context (ctx) and helper or properties you have passed in to context etc.
There are so many possible scenarios, (sometimes you need $parent.data.length, sometimes you want to get to sibling data, sibling view content, top-level view data, etc. etc.). I don’t want to provide for too many shortcut notations, since that will (at least slightly) impact performance, size and readability of compiled functions. And it requires for people to remember the shortcut notations.
There are many ways to provide custom ‘accessors’ including a simple helper function as in: {{=$ctx.parentData().section}}, or {{=$ctx.ancestorData(1).section}}, or {{=$ctx.section()}} etc. – by passing them in to the view.context() method on any view. You can pass the helpers in at top level if you want, and they will be avaialable also to all nested views.
As to a specific built-in way of passing in custom parameters declaratively to nested template contexts, I am considering a special syntax along the lines of {{#each myArray @outerSection=section}}{{=@outerSection}}, but it is not yet available…