Jquery knockout: Render template in-memory
Asked Answered
P

2

6

I have a knockout template:

<script id="draggableHelper" type="text/x-jquery-tmpl">
    <div class="draggableHelper">
        <span data-bind="text: Name"></span>
    </div>
</script>

Is possible to generate the result of the template, and save it into memory, by sending the object to populate the template?

Something like:

var result = ko.renderTemplate($("#draggableHelper").html(), { Name: "Test" });
Preoccupy answered 9/12, 2013 at 14:29 Comment(2)
I doubt it because Knockout is not a templating engine. At no point in time it builds "the HTML string" of something. You could subscribe() to an observable and grab the innerHTML from the appropriate node.Moyra
"Native templating is the mechanism that underpins foreach, if, with, and other control flow bindings. Internally, those control flow bindings capture the HTML markup contained in your element, and use it as a template to render against an arbitrary data item. This feature is built into Knockout and doesn’t require any external library" - knockoutjs.com/documentation/template-binding.htmlSlumgullion
T
14

Yes it's possible to apply bindings to nodes unattached to the DOM. Just use very useful function ko.applyBindingsToNode to achieve the desired result.

ko.renderTemplateX = function(name, data){
    // create temporary container for rendered html
    var temp = $("<div>");
    // apply "template" binding to div with specified data
    ko.applyBindingsToNode(temp[0], { template: { name: name, data: data } });
    // save inner html of temporary div
    var html = temp.html();
    // cleanup temporary node and return the result
    temp.remove();
    return html;
};

Take a look at this small example: http://jsfiddle.net/6s4gq/

Update:

Originally it was ko.renderTemplate method but there is built-in method in Knockout with the same name. Overriding ko.renderTemplate could stop working your application, especially if you're using template binding. Be careful!

Tilda answered 9/12, 2013 at 18:34 Comment(3)
WARNING: ko.renderTemplate is already defined in knockout. This evil code made me smash my head on the wall for two consecutive days trying to discover why all my 'not in memory' templates are causing 'out of stack space' error. Change its name please!Ostyak
@DaviFiamenghi, I cannot express how much I'm sorry for your loosely spent time! I've updated my answer. Thanks!Tilda
Haha thanks for your misericord, sir. And sorry for the drama, I was a little annoyed at the time of the answerOstyak
T
1

f_martinez's answer is really close to what I needed, I just had to specify the template engine to make it work. My function:

var renderTemplate = function (name, data) {
    // create temporary container for rendered html
    var temp = $("<div>");

    // apply "template" binding to div with specified data
    var options = {
        template: {
            name: name,
            data: data,
            templateEngine: new ko.nativeTemplateEngine()
        }
    };

    ko.applyBindingsToNode(temp[0], options);

    // save inner html of temporary div
    var html = temp.html();

    // cleanup temporary node and return the result
    temp.remove();

    return html;
};
Tincal answered 11/5, 2015 at 15:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.