Knockout with template binding
by Dejan Vasic
HTML
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<h1>People</h1>
<!--
<ul data-bind="foreach: people">
<li><span data-bind="text: name"><span></li>
</ul>
-->
<ul data-bind="template: { name: 'peopleList' }"></ul>
<script type="text/html" id="peopleList">
<% _.each(people(), function(person) { %>
<li>
<b><%= person.name %></b> is <%= person.age %> years old
</li>
<% }) %>
</script>
JavaScript
/* ---- Begin integration of Underscore template engine with Knockout. Could go in a separate file of course. ---- */
ko.underscoreTemplateEngine = function () { }
ko.underscoreTemplateEngine.prototype = ko.utils.extend(new ko.templateEngine(), {
renderTemplateSource: function (templateSource, bindingContext, options) {
// Precompile and cache the templates for efficiency
var precompiled = templateSource['data']('precompiled');
if (!precompiled) {
precompiled = _.template("<% with($data) { %> " + templateSource.text() + " <% } %>");
templateSource['data']('precompiled', precompiled);
}
// Run the template and parse its output into an array of DOM elements
var renderedMarkup = precompiled(bindingContext).replace(/\s+/g, " ");
return ko.utils.parseHtmlFragment(renderedMarkup);
},
createJavaScriptEvaluatorBlock: function(script) {
return "<%= " + script + " %>";
}
});
ko.setTemplateEngine(new ko.underscoreTemplateEngine());
/* ---- End integration of Underscore template engine with Knockout ---- */
var viewModel = {
people: ko.observableArray([
{ name: 'Rod', age: 123 },
{ name: 'Jane', age: 125 },
])
};
ko.applyBindings(viewModel);