Reputation: 2073
Please excuse if this particular question has been asked. I searched through blogs, thread in search of this but could not find anything particular to my needs.
I'm trying to build a single-page application with Knockout JS and I'm relatively new to this can't seem to wrap my head around this problem.
I have two templates:
<script id="template1" type="text/template">
<h3>Template 1</h3>
<button id="templButton" text="Go to template 2" />
</script>
and
<script id="template2" type="text/template">
<h3>Template 2</h3>
</script>
I have two div's that bind to these templates:
<div data-bind="template: { name: template1 }"></div>
<div data-bind="template: { name: template2 }"></div>
In template 1, I have a button that, when clicked, should populate template 2 and clear out template 1. There seems to be no way to do this, without another 3rd party addition?
Update 1
On page load, I use jQuery to get values for the first template:
$(document).ready(function(e) {
$.get("/Controller/Action", function (data) {
// get values from action, convert to array for ko to function
var results = $.parseJSON(data);
var viewModel = {
someBind = ko.mapping.fromJS(results);
}
ko.applyBindings(viewModel);
// now, I thought the best way to do this was to bind to the button here:
$("#templButton").click(function(e) {
// and call the load of the template here,
// however, because I have two templates on the page
// Knockout is trying to bind to both.
});
});
});
without using 'templateToUse' as so many posts, threads state, is there another way to do this? I'm very new to this all, so please excuse if my approach seems, stupid.
I've seen threads stating that the click event should be handled by Knockout:
<button data-bind="click: function(e) { ... }" />
but this brings me back to my original question, how can I load a second template, bind to it when the button is clicked.
Upvotes: 1
Views: 5941
Reputation: 114792
If your goal is to do this with a single div, then one approach is to do:
<script id="template1" type="text/template">
<h3>Template 1</h3>
<button id="templButton" data-bind="click: swap">Go to template 2</button>
</script>
<script id="template2" type="text/template">
<h3>Template 2</h3>
</script>
<div data-bind="template: theTemplate"></div>
With a view model like:
ko.applyBindings({
theTemplate: ko.observable("template1"),
swap: function() {
this.theTemplate("template2");
}
});
So, you store the name of the template in an observable and update it. Sample: http://jsfiddle.net/rniemeyer/SfaPH/
If you really did want this in two divs, then you would need to have a flag to say which one is rendered or visible like:
Bind it like:
<div data-bind="template: { name: 'template1', 'if': one }"></div>
<div data-bind="template: { name: 'template2', ifnot: one }"></div>
With a view model like:
ko.applyBindings({
one: ko.observable(true),
swap: function() {
this.one(false);
}
});
Sample: http://jsfiddle.net/rniemeyer/n2y6z/
Upvotes: 10