KO dynamically change template

Load a different template based on selection from href and select list

by kougiland

HTML

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<div id="main"> <!-- only here to assess impact on KO nested templating -->
    <!-- header portion -->
    <span data-bind="text: console.log($data)"></span>
    <div id="header">
        <ul data-bind="foreach: panels">
        <li><a href="#" data-bind="click: $parent.goto, text:'Load '+$data"></a></li>
    </ul>
    </div>

    <!-- hot-swap content panel -->
    <div id="content" data-bind="template: { name: currentPanelData().panel, data: currentPanelData().data }"></div>
    
</div> <!-- Effective end of page -->
    
<script type="text/html" id="dogs-template">
   <div id="dogPanel">
    <!-- DEBUG --> <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
   <h3>Dog Breeds:</h3>    
   <ul data-bind="foreach: dogs">
       <li data-bind="text: breed"></li>
    </ul>
  </div>
</script>

<script type="text/html" id="cats-template">   
   <div id="catPanel">
    <!-- DEBUG --> <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
   <h3>Cat Breeds</h3>    
   <ul data-bind="foreach: cats">
       <li data-bind="text: breed"></li>
    </ul>
    </div>
</script>

JavaScript

<!-- Function Panel 1 -->

Cat = function(breed,maxSize){
    this.breed = ko.observable(breed);
    this.maxSize = ko.observable(maxSize);
}
CatViewModel = function(){
    var self = this;
    
    self.cats = ko.observableArray();

    self.cats.push(new Cat("Angora","14"));
    self.cats.push(new Cat("Siamese","12"));    
    self.cats.push(new Cat("Tabby","13"));    
}


<!-- Function Panel 2 -->

Dog = function(breed,maxSize){
    this.breed = ko.observable(breed);
    this.maxSize = ko.observable(maxSize);
}
DogViewModel = function(){
    var self = this;
    
    self.dogs = ko.observableArray();

    self.dogs.push(new Cat("St. Bernard","140"));
    self.dogs.push(new Cat("Retreiver","90"));    
    self.dogs.push(new Cat("Scottie","30"));    
}  

  <!-- Main App State -->
   AppViewModel = function(){
      var self = this;
       
       self.panels = [
           "cats",
           "dogs"
       ];
       var panelViewModels = {
           "cats" : new CatViewModel(),
           "dogs" : new DogViewModel()
       };
       
       self.panelName = ko.observable('cats-template');
       self.panelData = ko.observable(panelViewModels["cats"]);
       
       self.currentPanelData = ko.observable({
           panel : 'cats-template',
           data : panelViewModels["cats"]
       });
       
      self.currentPanel = function() {
          return self.currentPanel()['panel'];
      };
       
      self.goto = function(name) {
          console.log('changing to panel: ' + name);
          self.currentPanelData()['panel'] = name + "-template";
          self.currentPanelData()['data'] = panelViewModels[name];
          self.currentPanelData.valueHasMutated();
      }
   }
   
appViewModel = new AppViewModel();
ko.applyBindings(appViewModel)