title: Recursive Knockout list - setting selected value without jQuery
body: <p>I tend to regret using jQuery within a Knockout Viewmodel if I'm trying to change the style or visibility of an element. So I'm guessing there's a better way of doing this:</p>
  
  <p>I have some recursive Knockout View Models to display a tree structure of Companies, the managers in those companies and any companies under those managers and on and on (hence the recursive-ness).</p>
  
  <p>How can I set an observable in a child (ManagerViewModel) from within a $root (ApproverViewModel) when I'm creating these objects recursively? Currently I'm doing it with jQuery, and setting the value of a hidden element, but that seems to go against the observable pattern of KO - that makes me think there's a better way of which I'm just unaware.</p>
  
  <p>In the MangerViewModel I'm setting <code>_self.DefaultApproverClass()</code> the first time the page loads. Then when the user selects a different Manager I just remove all the classes, find the ID of the newly selected element and apply a CSS class to it. </p>
  
  <p>I'm guessing there's a better, more "Knockout recursion" way of doing this. Any suggestions?</p>
  
  <p>Here's a somewhat slimmed down version of my ViewModels (<a href="http://jsfiddle.net/barryman9000/H9V7g/6/" rel="nofollow">the complete version is in this JSFiddle</a>)</p>
  
  <pre><code>be.ApproverViewModel = function (data) {
      var _self = this;
  
      _self.UserCompanies = ko.observableArray(
          ko.utils.arrayMap(data.userCompanies, function (item) {
              return new be.CompanyViewModel(item);
          })
      );
      _self.SetSelectedManager = function (data, event) {
          // remove all classes, then add the selected class to the selected element
          $('.selectedApprover').removeClass('selectedApprover');
          $('#' + data.ClientID()).addClass('selectedApprover');
          // set UI elements
          $('#selectedClientID').text(data.ClientID());
          $('#selectedManagerName').text(data.ManagerName());
      };
      _self.GetSelected = function (data, event) {
          console.log($('#selectedClientID').text());
      };
  };
  
  be.CompanyViewModel = function (data) {
      var _self = this;
      ko.mapping.fromJS(data, {}, _self);
  
      _self.Companies = ko.observableArray(
          ko.utils.arrayMap(data.Companies, function (item) {
              return new be.CompanyViewModel(item);
          })
      );
      _self.Managers = ko.observableArray(
          ko.utils.arrayMap(data.Managers, function (item) {
              return new be.ManagerViewModel(item);
          })
      );
  };
  be.ManagerViewModel = function (data) {
      var _self = this;
      ko.mapping.fromJS(data, {}, _self);
  
      _self.DefaultApproverClass = ko.observable('');
      _self.SubordinateMgrs = ko.observableArray(
          ko.utils.arrayMap(data.SubordinateMgrs, function (item) {
              return new be.ManagerViewModel(item);
          })
      );
      // Styles
  
      _self.LoadStyleSelected = function () {
          if (_self.IsDefaultApprover()) {
              _self.DefaultApproverClass('selectedApprover');
              $('#selectedManagerName').text(_self.ManagerName());
              $('#selectedClientID').text(_self.ClientID());
          }
      };
      // just call it the first time
      _self.LoadStyleSelected();
  
  };
  </code></pre>
  
  <p>The Markup</p>
  
  <pre><code>&lt;div id="CompanyTree"&gt;
      &lt;div class="selectedApproverHeader"&gt;
          &lt;h4 class="lighter smaller"&gt;Currently Selected Approver:
          &lt;br /&gt;
              &lt;span id="selectedManagerName"&gt;&lt;/span&gt;,
              ID: &lt;span id="selectedClientID"&gt;&lt;/span&gt;
          &lt;/h4&gt;
      &lt;/div&gt;
      &lt;div class="approver-list-contaier"&gt;
          &lt;ul data-bind="template: { name: 'companyElement', foreach: UserCompanies }"&gt;&lt;/ul&gt;
      &lt;/div&gt;
      &lt;script id="companyElement" type="text/html"&gt;
          &lt;li class="companyList"&gt;
              &lt;h4 class="smaller" data-bind="text: CompanyName"&gt;&lt;/h4&gt;
              &lt;ul class="managerList" data-bind="template: { name: 'managerElement', foreach: Managers }"&gt;&lt;/ul&gt;
              &lt;ul data-bind="template: { name: 'companyElement', foreach: Companies }"&gt;&lt;/ul&gt;
          &lt;/li&gt;
      &lt;/script&gt;
      &lt;script id="managerElement" type="text/html"&gt;
          &lt;li class="managerList"&gt;
              &lt;span data-bind="text: ManagerName, attr: { id: ClientID },  css: DefaultApproverClass, click: $root.SetSelectedManager"&gt;&lt;/span&gt;
              &lt;ul data-bind="template: { name: 'managerElement', foreach: SubordinateMgrs }"&gt;
              &lt;/ul&gt;
          &lt;/li&gt;
      &lt;/script&gt;
      &lt;div&gt;
          &lt;button data-bind="click:$root.GetSelected"&gt;Click Me&lt;/button&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>