title: How to use knockout.js with ASP.NET MVC ViewModels?
body: <p><strong>Bounty</strong></p>
  
  <p>It's been awhile and I still have a couple outstanding questions. I hope by adding a bounty maybe these questions will get answered.</p>
  
  <ol>
  <li>How do you use html helpers with knockout.js</li>
  <li><p>Why was document ready needed to make it work(see first edit for more information)</p></li>
  <li><p>How do I do something like this if I am using the knockout mapping with my view models? As I do not have a function due to the mapping.</p>
  
  <pre><code>function AppViewModel() {
  
      // ... leave firstName, lastName, and fullName unchanged here ...
  
      this.capitalizeLastName = function() {
  
      var currentVal = this.lastName();        // Read the current value
  
      this.lastName(currentVal.toUpperCase()); // Write back a modified value
  
  };
  </code></pre></li>
  <li><p>I want to use plugins for instance I want to be able to rollback observables as if a user cancels a request I want to be able to go back to the last value. From my research this seems to be achieved by people making plugins like <a href="https://github.com/romanych/ko.editables">editables </a></p>
  
  <p>How do I use something like that if I am using mapping? I really don’t want to go to a method where I have in my view manual mapping were I map each MVC viewMode field to a KO model field as I want as little inline javascript as possible and that just seems like double the work and that’s why I like that mapping.</p></li>
  <li><p>I am concerned that to make this work easy (by using mapping) I will lose a lot of KO power but on the other hand I am concerned that manual mapping will just be a lot of work and will make my views contain too much information and might become in the future harder to maintain(say if I remove a property in the MVC model I have to move it also in the KO viewmodel) </p></li>
  </ol>
  
  <p><hr />
  <strong>Original Post</strong></p>
  
  <p>I am using asp.net mvc 3 and I looking into knockout as it looks pretty cool but I am having a hard time figuring out how it works with asp.net mvc especially view models.</p>
  
  <p>For me right now I do something like this</p>
  
  <pre><code> public class CourseVM
      {
          public int CourseId { get; set; }
          [Required(ErrorMessage = "Course name is required")]
          [StringLength(40, ErrorMessage = "Course name cannot be this long.")]
          public string CourseName{ get; set; }
  
  
          public List&lt;StudentVm&gt; StudentViewModels { get; set; }
  
  }
  </code></pre>
  
  <p>I would have a Vm that has some basic properties like CourseName and it will have some simple validation on top of it. The Vm model might contain other view models in it as well if needed.</p>
  
  <p>I would then pass this Vm to the View were I would use html helpers to help me display it to the user.</p>
  
  <pre><code>@Html.TextBoxFor(x =&gt; x.CourseName)
  </code></pre>
  
  <p>I might have some foreach loops or something to get the data out of the collection of Student View Models.</p>
  
  <p>Then when I would submit the form I would use jquery and <code>serialize array</code> and send it to a controller action method that would bind it back to the viewmodel.</p>
  
  <p>With knockout.js it is all different as you now got viewmodels for it and from all the examples I seen they don't use html helpers.</p>
  
  <p>How do you use these 2 features of MVC with knockout.js?</p>
  
  <p>I found <a href="http://channel9.msdn.com/posts/ASPNET-MVC-With-Community-Tools-Part-11-KnockoutJS?format=html5"> this video</a> and it briefly(last few minutes of the video @ 18:48) goes into a way to use viewmodels by basically having an inline script that has the knockout.js viewmodel that gets assigned the values in the ViewModel.</p>
  
  <p>Is this the only way to do it? How about in my example with having a collection of viewmodels in it? Do I have to have a foreach loop or something to extract all the values out and assign it into knockout?</p>
  
  <p>As for html helpers the video says nothing about them. </p>
  
  <p>These are the 2 areas that confuses the heck out of me as not many people seem to talk about it and it leaves me confused of how the initial values and everything is getting to the view when ever example is just some hard-coded value example.</p>
  
  <p><hr />
  <strong>Edit</strong></p>
  
  <p>I am trying what Darin Dimitrov has suggested and this seems to work(I had to make some changes to his code though). Not sure why I had to use document ready but somehow everything was not ready without it.</p>
  
  <pre><code>@model MvcApplication1.Models.Test
  
  @{
      Layout = null;
  }
  
  &lt;!DOCTYPE html&gt;
  
  &lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;Index&lt;/title&gt;
      &lt;script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"&gt;&lt;/script&gt;
      &lt;script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"&gt;&lt;/script&gt;
      &lt;script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"&gt;&lt;/script&gt;
     &lt;script type="text/javascript"&gt;
  
     $(function()
     {
        var model = @Html.Raw(Json.Encode(Model));
  
  
  // Activates knockout.js
  ko.applyBindings(model);
     });
  
  &lt;/script&gt;
  
  &lt;/head&gt;
  &lt;body&gt;
      &lt;div&gt;
          &lt;p&gt;First name: &lt;strong data-bind="text: FirstName"&gt;&lt;/strong&gt;&lt;/p&gt;
          &lt;p&gt;Last name: &lt;strong data-bind="text: LastName"&gt;&lt;/strong&gt;&lt;/p&gt;
          @Model.FirstName , @Model.LastName
      &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>I had to wrap it around a jquery document ready to make it work.</p>
  
  <p>I also get this warning. Not sure what it is all about.</p>
  
  <pre><code>Warning 1   Conditional compilation is turned off   -&gt; @Html.Raw
  </code></pre>
  
  <p>So I have a starting point I guess at least will update when I done some more playing around and how this works.</p>
  
  <p>I am trying to go through the interactive tutorials but use the a ViewModel instead.</p>
  
  <p>Not sure how to tackle these parts yet </p>
  
  <pre><code>function AppViewModel() {
      this.firstName = ko.observable("Bert");
      this.lastName = ko.observable("Bertington");
  }
  </code></pre>
  
  <p>or</p>
  
  <pre><code>function AppViewModel() {
      // ... leave firstName, lastName, and fullName unchanged here ...
  
      this.capitalizeLastName = function() {
          var currentVal = this.lastName();        // Read the current value
          this.lastName(currentVal.toUpperCase()); // Write back a modified value
      };
  </code></pre>
  
  <p><hr />
  <strong>Edit 2</strong></p>
  
  <p>I been able to figure out the first problem. No clue about the second problem. Yet though. Anyone got any ideas?</p>
  
  <pre><code> @model MvcApplication1.Models.Test
  
      @{
          Layout = null;
      }
  
      &lt;!DOCTYPE html&gt;
  
      &lt;html&gt;
      &lt;head&gt;
          &lt;title&gt;Index&lt;/title&gt;
          &lt;script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"&gt;&lt;/script&gt;
          &lt;script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"&gt;&lt;/script&gt;
         &lt;script type="text/javascript"&gt;
  
         $(function()
         {
          var model = @Html.Raw(Json.Encode(Model));
          var viewModel = ko.mapping.fromJS(model);
          ko.applyBindings(viewModel);
  
         });
  
      &lt;/script&gt;
  
      &lt;/head&gt;
      &lt;body&gt;
          &lt;div&gt;
              @*grab values from the view model directly*@
              &lt;p&gt;First name: &lt;strong data-bind="text: FirstName"&gt;&lt;/strong&gt;&lt;/p&gt;
              &lt;p&gt;Last name: &lt;strong data-bind="text: LastName"&gt;&lt;/strong&gt;&lt;/p&gt;
  
              @*grab values from my second view model that I made*@
              &lt;p&gt;SomeOtherValue &lt;strong data-bind="text: Test2.SomeOtherValue"&gt;&lt;/strong&gt;&lt;/p&gt;
              &lt;p&gt;Another &lt;strong data-bind="text: Test2.Another"&gt;&lt;/strong&gt;&lt;/p&gt;
  
              @*allow changes to all the values that should be then sync the above values.*@
              &lt;p&gt;First name: &lt;input data-bind="value: FirstName" /&gt;&lt;/p&gt;
              &lt;p&gt;Last name: &lt;input data-bind="value: LastName" /&gt;&lt;/p&gt;
              &lt;p&gt;SomeOtherValue &lt;input data-bind="value: Test2.SomeOtherValue" /&gt;&lt;/p&gt;
              &lt;p&gt;Another &lt;input data-bind="value: Test2.Another" /&gt;&lt;/p&gt;
  
             @* seeing if I can do it with p tags and see if they all update.*@
              &lt;p data-bind="foreach: Test3"&gt;
                  &lt;strong data-bind="text: Test3Value"&gt;&lt;/strong&gt; 
              &lt;/p&gt;
  
       @*took my 3rd view model that is in a collection and output all values as a textbox*@       
      &lt;table&gt;
          &lt;thead&gt;&lt;tr&gt;
              &lt;th&gt;Test3&lt;/th&gt;
          &lt;/tr&gt;&lt;/thead&gt;
            &lt;tbody data-bind="foreach: Test3"&gt;
              &lt;tr&gt;
                  &lt;td&gt;    
                      &lt;strong data-bind="text: Test3Value"&gt;&lt;/strong&gt; 
  &lt;input type="text" data-bind="value: Test3Value"/&gt;
                  &lt;/td&gt;
              &lt;/tr&gt;    
          &lt;/tbody&gt;
      &lt;/table&gt;
  </code></pre>
  
  <p>Controller</p>
  
  <pre><code>  public ActionResult Index()
      {
                Test2 test2 = new Test2
          {
              Another = "test",
              SomeOtherValue = "test2"
          };
  
          Test vm = new Test
          {
              FirstName = "Bob",
              LastName = "N/A",
               Test2 = test2,
  
          };
          for (int i = 0; i &lt; 10; i++)
          {
              Test3 test3 = new Test3
              {
                  Test3Value = i.ToString()
              };
  
               vm.Test3.Add(test3);
          }
  
          return View(vm);
      }
  </code></pre>