Preparation Code Preparation HTML (this will be inserted in the <body>
of a valid HTML5 document in standards mode) (useful when testing DOM operations or including libraries) <script src ="http://underscorejs.org/underscore-min.js" > </script >
<script src ="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.min.js" > </script >
<script src ='http://knockoutjs.com/downloads/knockout-3.1.0.js' > </script >
<script src ='https://rawgithub.com/olado/doT/master/doT.min.js' > </script >
<script >
ko.underscoreTemplateEngine = function ( ) {
var engine = this ;
this .getTemplateNode = function (template ) {
return document .getElementById (template);
};
this .renderTemplate = function (templateId, data, options ) {
var tmpl = engine.getTemplateNode (templateId).text ;
var html = _.template (tmpl)(data);
return ko.utils .parseHtmlFragment (html);
};
this .rewriteTemplate = function (template, rewriterCallback ) {
var templateNode = engine.getTemplateNode (template);
var rewritten = rewriterCallback (templateNode.text );
var each = /(_\s*\.\s*each\s*\(\s*[^,]+\s*,\s*function\s*\(\s*)([^)]+)(\s*\)\s*{)/gi ;
rewritten = rewritten.replace (each, '$1$2$3 with($2)' );
templateNode.text = rewritten;
templateNode.isRewritten = true ;
};
this .isTemplateRewritten = function (templateId ) {
return engine.getTemplateNode (templateId).isRewritten === true ;
};
this .createJavaScriptEvaluatorBlock = function (script ) {
return '<%= ' + script + ' %>' ;
};
};
ko.underscoreTemplateEngine .prototype = new ko.templateEngine ();
</script >
<script >
ko.handlebarsTemplateEngine = function ( ) { }
ko.handlebarsTemplateEngine .prototype = ko.utils .extend (new ko.templateEngine (), {
templates : {},
renderTemplateSource : function (templateSource, bindingContext, options ) {
var data = bindingContext.$data ,
templateId = options,
templateText = templateSource.text (),
compiledTemplate = this .templates [templateId];
if (compiledTemplate == null ) {
compiledTemplate = Handlebars .compile (templateText);
this .templates [templateId] = compiledTemplate;
}
return ko.utils .parseHtmlFragment (compiledTemplate (data));
},
allowTemplateRewriting : false
});
</script >
<script >
ko.dotTemplateEngine = function ( ) { }
ko.dotTemplateEngine .prototype = ko.utils .extend (new ko.templateEngine (), {
templates : {},
renderTemplateSource : function (templateSource, bindingContext, options ) {
var data = bindingContext.$data ,
templateId = options,
templateText = templateSource.text (),
compiledTemplate = this .templates [templateId];
if (compiledTemplate == null ) {
compiledTemplate = doT.template (templateText);
this .templates [templateId] = compiledTemplate;
}
return ko.utils .parseHtmlFragment (compiledTemplate (data));
},
allowTemplateRewriting : false
});
</script >
<div id ="native-test-virtual" >
<h2 > Native (virtual foreach)</h2 >
<div class ="messages" data-bind ="template:'ko-native'" > </div >
</div >
<div id ="handlebars-test" >
<h2 > Handlebars</h2 >
<div class ="messages" data-bind ="template:'ko-handlebars'" > </div >
</div >
<div id ="underscore-test" >
<h2 > Underscore</h2 >
<div class ="messages" data-bind ="template:'ko-underscore'" > </div >
</div >
<div id ="dot-test" >
<h2 > doT</h2 >
<div class ="messages" data-bind ="template:'ko-dot'" > </div >
</div >
<script id ="ko-native" type ="text/html" >
<div >
<span data-bind ="text: $data.name" > </span > ,
<span data-bind ="text:$data.age" > </span > <br >
<ul data-bind ="foreach: $data.likes" >
<li data-bind ="text: $data" > </li >
</ul >
</div >
</script >
<script id ="ko-underscore" type ="text/html" >
<% _.each ($root.items (), function (item ) { %>
<div >
<span data-bind ="text: item.name" > </span > ,
<span data-bind ="text:item.age" > </span > <br >
<ul >
<% _.each(item.likes(), function (like) { %>
<li data-bind ="text: like" > </li >
<% }); %>
</ul >
</div >
<% }); %>
</script >
<script id ="ko-handlebars" type ="text/x-handlebars-template" >
{{# each items }}
<div >
<span data-bind ="text: '{{name}}'" > </span > ,
<span data-bind ="text: '{{age}}'" > </span > <br >
<ul >
{{# each likes }}
<li data-bind ="text: '{{this}}'" > </li >
{{/ each }}
</ul >
</div >
{{/ each }}
</script >
<script id ="ko-dot" type ="text/html" >
{{~ it.items() :item }}
<div >
<span > {{=item.name()}}</span > ,
<span > {{=item.age()}}</span > <br >
<ul >
{{~ item.likes() :like }}
<li > {{= like}}</li >
{{~}}
</ul >
</div >
{{~}}
</script >
Setup JS var nativeNodeVirtual = document .getElementById ('native-test-virtual' );
var handlebarsNode = document .getElementById ('handlebars-test' );
var underscoreNode = document .getElementById ('underscore-test' );
var dotNode = document .getElementById ('dot-test' );
var nativeTemplateEngine = new ko.nativeTemplateEngine ();
var handlebarsTemplateEngine = new ko.handlebarsTemplateEngine ();
var underscoreTemplateEngine = new ko.underscoreTemplateEngine ();
var dotTemplateEngine = new ko.dotTemplateEngine ();
var data = (function (n ) {
var data = [], i;
for (i = 0 ; i < n; i++) {
data.push ({
name : ko.observable ('Greg' ),
age : ko.observable (i),
likes : ko.observableArray (['movies' ,'reading' ,'gaming' ,'tv' ,'books' ,'sports' ])
});
}
return data;
}(250 ));
var viewmodel = { items : ko.observableArray ( data ) };
Teardown JS