//define a template source that simply treats the template name as its content ko.templateSources.stringTemplate = function(template, templates) { this.templateName = template; this.templates = templates; } ko.utils.extend(ko.templateSources.stringTemplate.prototype, { data: function(key, value) { console.log("data", key, value, this.templateName); this.templates._data = this.templates._data || {}; this.templates._data[this.templateName] = this.templates._data[this.templateName] || {}; if (arguments.length === 1) { return this.templates._data[this.templateName][key]; } this.templates._data[this.templateName][key] = value; }, text: function(value) { console.log("text", value, this.templateName) if (arguments.length === 0) { return this.templates[this.templateName]; } this.templates[this.templateName] = value; } }); //modify an existing templateEngine to work with string templates function createStringTemplateEngine(templateEngine, templates) { templateEngine.makeTemplateSource = function(template) { return new ko.templateSources.stringTemplate(template, templates); } return templateEngine; } //actual page code function Item(id, name) { return { id: ko.observable(id), name: ko.observable(name) } } var viewModel = { templates: { viewTemplate: "<li data-bind='text: name'></li>", editTemplate: "<li><input data-bind='value: name' /></li>" }, isEditable: ko.observable(false), items: ko.observableArray([ new Item(1, "pencil"), new Item(2, "pen"), new Item(3, "marker") ]), addItem: function() { this.items.push(new Item(0, "new")); }, whichTemplateToUse: function() { return viewModel.isEditable() ? 'editTemplate' : 'viewTemplate'; } }; //make this new template engine our default engine ko.setTemplateEngine(createStringTemplateEngine(new ko.nativeTemplateEngine(), viewModel.templates)); ko.applyBindings(viewModel);
Editable: <input type="checkbox" data-bind="checked: isEditable" /> <h2>Items</h2> <ul data-bind="template: { name: whichTemplateToUse, foreach: items }"></ul> <button data-bind="click: addItem">Add</button>
h2 { font-size: 1.1em; font-weight: bold; }