I'm using the following:
What I'm trying to achieve is the following:
I'm guessing the reason it doesn't work, is because the Template is loaded before the VM (it does give me binding errors).
The structure of my site is as like this (excl. the libraries stated above):
index.html
(Holds the template container)js/script.js
(Holds the main ViewModel)js/firstvm.js
(Holds the first ViewModel)js/secondvm.js
(Holds the second ViewModel)tmpl/firstvm.html
(Template for the first VM)tmpl/secondvm.html
(Template for the second VM)Or simply download the source and view the problem.
Most important parts:
index.html
<button data-bind="click: loadFirstPage">Load first page + ViewModel</button>
<button data-bind="click: loadSecondPage">Load second page + ViewModel</button>
< hr />
<div data-bind="template: { name: function() { return currentTemplate(); }, data: currentData }"></div>
script.js
function IndexViewModel() {
var vm = this;
this.currentTemplate = ko.observable();
this.currentData = ko.observable();
this.loadFirstPage = function() {
vm.currentTemplate("firstvm");
vm.currentData(new FirstViewModel());
};
this.loadSecondPage = function() {
vm.currentTemplate("secondvm");
vm.currentData(new SecondViewModel());
};
this.loadFirstPage();
};
ko.applyBindings(new IndexViewModel());
firstvm.html
<p data-bind="text: displayValue"></p>
secondvm.html
<p data-bind="text: displayValue2"></p>
firstvm.js
function FirstViewModel() {
this.displayValue = ko.observable("Text from firstvm.js");
};
secondvm.js
function SecondViewModel() {
this.displayValue2 = ko.observable("Text from secondvm.js");
};
I hope somebody can help me out with this one. Thanks in advance!
Ps. Forgot to mention: When the "First page" button is pressed twice, it does seem to work (probably since the correct VM is loaded).
So it looks like the issue is that the name and data need to change at the same time, so that the template isn't binding to a viewmodel that isn't there yet. There are a few ways you could solve this. One would be loading the templates and keeping them, but you could continue reloading them like this:
Template Binding:
<div data-bind="template: {name: currentTemplate().name(),
data: currentTemplate().data() }"></div>
ViewModel:
function TemplateViewModel(name, data) {
this.name = ko.observable(name);
this.data = ko.observable(data);
};
function IndexViewModel() {
var vm = this;
this.currentTemplate = ko.observable();
this.loadFirstPage = function() {
vm.currentTemplate(new TemplateViewModel("firstvm", new FirstViewModel()));
};
this.loadSecondPage = function() {
vm.currentTemplate(new TemplateViewModel("secondvm", new SecondViewModel()));
};
this.loadFirstPage();
};
ko.applyBindings(new IndexViewModel());
I tested this, it works. You may want to tweak it a bit more, but you get the idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With