I need to use the underscore template instead of the default KnockoutJS template engine due to performance. However, since I\'m in an asp.net environment th
You're asking how to change Underscore's delimiter characters? This SO answer seems to have the right answer. Basically, you can define your own regex for nesting data:
_.template("hello <?= name ?>", {"name": "Mike"}, {"interpolate": /<?=([\s\S]+?)%>/g) ?>})
A couple of side notes:
You say you're using Underscore, instead of Knockout's native template engine, for performance reasons. As an avid Knockout user, this sounds fishy. Knockout's native template engine is very fast and ultimately tested far more than 3rd party engines plugged into Knockout. I've built numerous applications with KO and never had an issue with the template engine being too slow. Make sure you really need to use Underscore. For the vast majority of cases, Knockout's native template engine works perfectly fine.
Secondly, are you aware of the Razor syntax? This wouldn't interfere with Underscore.
HTML
<h1>People</h1>
<ul data-bind="template: { name: 'peopleList' }"></ul>
<script type="text/html" id="peopleList">
{{ _.each(people(), function(person) { }}
<li>
<b data-bind="text: person.name"></b> is {{= person.age }} years old
</li>
{{ }) }}
</script>
<p>This shows that you can use both Underscore-style evaluation (<%= ... %>) <em>and</em> data-bind attributes in the same templates.</p>
JS
/* ---- 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) {
_.templateSettings = {
interpolate: /\{\{=(.+?)\}\}/g,
escape: /\{\{-(.+?)\}\}/g,
evaluate: /\{\{(.+?)\}\}/g
};
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);
The _.templateSettings
configuration is global, so just add the block
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
anywhere earlier in your code.