Using a variable to store a knockout template

谁都会走 提交于 2019-12-22 23:24:16

问题


New to knockout and loving it so far cut a 700 line jQuery mess into 150 lines. The one part I am not really liking is the templating. I want to be able to create a file similar to this

module.ViewModel.views = {
   'view1' : '<div data-bind="foreach: data">TEMPLATE</div>'
};

// in my view model set something like 
ViewModel.view1Template = module.ViewModel.views.view1;

// then in my html have
<div data-bind="template: view1Template()"></div>

I would like to be able to do this possibly with mustache if that matters but really I just want to add reusability to my templates not a fan of having them referenced by IDs directly in the html. The other reason I would like to do this is in my views folder I have other templates that use mustache but not knockout would like to keep my formatting consistent across all JS templates.

UPDATE

The answer below seems like currently the closest thing to what I want to do I did it slightly different

for (var view in module.views){
    var node = $("<script/>", {
        "type" : "text/html",
        "id" : view,
        "text" : module.views[view]
    }).appendTo("body");
}

回答1:


You can insert the elements into the DOM dynamically and apply the ko binding afterwards:

var html = $.parseHtml(module.ViewModels.views['view1'])[0];
ko.applyBindings(model, html);
$('#content').append(html);

Live demo

http://jsfiddle.net/bikeshedder/VHUcF/


I just realized that I might have answered only half of your question. Sadly the template binding handler only accepts an element id as argument and no elements. This however is easy to fix by adding the templates to the DOM before applying the bindings:

HTML

<script id="templates" type="text/html"></script>

<div id="content" data-bind="template: templates.answerList.id"></div>

JavaScript

var templates = {
    answerList: '<ul class="answer-list" data-bind="template: { name: templates.answer.id, foreach: answers }"></ul>',
    answer: '<div class="answer" data-bind="text: text"></div>'
};

// insert templates into DOM
for (var name in templates) {
    var html = templates[name];
    var element = document.createElement('div');
    $(element).append($.parseHTML(html)[0]);
    element.id = 'tpl_' + name;
    $(element).attr('id', element.id);
    templates[name] = element;
    $('#templates').append(element);
}

answerModel = {
    answers: [
        { text: 1 },
        { text: 42 },
        { text: 667 }
    ],
    templates: templates
};

ko.applyBindings(answerModel, $('#content')[0]);

Live demo

http://jsfiddle.net/bikeshedder/VHUcF/1/




回答2:


I just came up with a better solution to this problem. It no longer requires you to add a ".name" when specifying the template.

HTML

<script id="templates" type="text/html"></script>

<div id="content" data-bind="template: templates.answerList"></div>

JavaScript

var templates = {
    answerList: 'Answers: <ul class="answer-list" data-bind="template: { name: templates.answer, foreach: answers }"></ul>',
    answer: '<li class="answer" data-bind="text: text"></li>'
};

var templateIds = {};

for (var name in templates) {
    var id = 'tpl_' + name;
    $(document.createElement('div'))
        .append($.parseHTML(templates[name]))
        .attr('id', 'tpl_' + name)
        .appendTo('#templates');
    templateIds[name] = id;
}

answerModel = {
    answers: [
        { text: 1 },
        { text: 42 },
        { text: 667 }
    ],
    templates: templateIds
};

ko.applyBindings(answerModel, $('#content')[0]);

Live demo

http://jsfiddle.net/bikeshedder/VHUcF/3/

Note

This attempt requires you to either pass the templates as model attribute or define templates at the global scope. You can also just write "tpl_" + ' which I find even more natural to use.

<div data-bind="template: 'tpl_answers'"></div>

If you do not want to put the script element containing the templates in the HTML just create it from the JavaScript as well.



来源:https://stackoverflow.com/questions/14611936/using-a-variable-to-store-a-knockout-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!