Reputation: 25
Essentially I am trying to implement RobN's extremely simple template switcher http://jsfiddle.net/rniemeyer/XYz8M/ which uses 'template' data binding.
(---SO wants code here - see fiddle for complete code---)
<div id="templateContent" data-bind='template: { name: currentView() }'></div>
var viewModel = {
currentView: ko.observable("template-1"),
toggleView: function() {
this.currentView(this.currentView() === "template-1" ? "template-2" : "template-1");
}
};
ko.applyBindings(viewModel);
I have seen a lot of other simple examples doing this and all are using the same viewModel class for each loaded template. Exception - RobN's SamplePresentation app (I don't have enough rep points to post another link) while very impressive I found hard to connect to my noobie KO experience. I think he is doing this in his section.activate() method, but, it's unclear to me.
I want to use this concept in a real app, but having binding context issues. Here is what I am trying to do: http://jsfiddle.net/jockor/DSEDh/4/
This line intentionally left blank (please see fiddle vs. mangling code here)
Basically when a nav link/button is pressed I simply want to swap out the body content panel with another template. That template will need its own data backed by its own viewModel.
The fiddle above is my go at a simplified version of this concept - just trying to switch between the Cats and Dogs panels. What I encounter is that the data bound to the 'template' data-bind is used for the loaded cat/dog templates.
Can someone tell me if I am doing this correctly, or if I am abusing the 'template' binding concept?
Upvotes: 1
Views: 1226
Reputation: 4821
I have modified your jsfiddle to work:
What you needed was to switch the data
field of the template binding as well. You were only switching the template name and I could see from your code that you were looking for a way to change the view model data as well. So, I crudely implemented it so that it switches the data from viewModel to viewModel when it switches the name. There are more elegant ways to do this, but the jsfiddle was just for demonstration.
By changing the data
you can modify what the template points to to fetch its data. By making that observable, I was able to have the data that it points at switch. My quick crude implementation above uses a simple object that holds both the template name and the data inside an observable. Since the name of the template and the data have to switch at the same time, I update the values in the object inside the observable and then manually tell the observable that its value has changed. If you change the data before the name of the template, it will try binding the previous template. By the same, if you change the name before the data, it will try binding the old data to the new template. So, in order to do this without it blowing up about not finding variables and stuff when re-binding the template you need to make sure somehow that your template
binding doesn't update before you are done changing both the name of the template and the data to point to.
EDIT: I noticed that you had a function handler in your knockout bindings that was passing $data as the first argument to a function. Knockout always passes $data as the first argument to a function in the first place, so I replaced your function () { ....goto($data); }
with ....goto
(... = stuff). This is just sort of a side node (and didn't even require any modification to your function signature).
Upvotes: 1