impress.js CDN | Free impress.js hosting on NetDNA's Content Delivery Network

Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

MVVM with

KnockoutJS

Why Model View View Model?
Separation of code:

Let your html be html, your javascript be javascript, and your c# be c#!

Turn this:
<ul id="products">
  @for(int i=0; i < Model.Products.Length; i++)
  {
    var selectedClass = "";
    if(x.Products[i].Selected)
    {
      selectedClass = "selected";
    }
    <li class="@selectedClass">
      @Html.HiddenFor(x=>x.Products[i].Id);
      @Html.CheckboxFor(x=>x.Products[i].Selected);
      <span class="productName">@Model.Products[i].Name</span> ($<span class="productPrice">@Model.Products[i].Price</span>)
    </li>
  }
</ul>
<div>Total Price:
  $<span id="totalPrice">@Model.Products.Where(x=>x.Selected).Sum(x=>x.Price)</span>
</div>
    
Separation of code:

Let your html be html, your javascript be javascript, and your c# be c#!

Into this:
<ul id="products" data-bind="foreach: products">
<li data-bind="css: { selected: selected }">
    <input type="checkbox" data-bind="checked: selected" />
    <span data-bind="text: name"></span> ($<span data-bind="text: price"></span>)
  </li>
</ul>
<div>Total Price:
  $<span id="totalPrice" data-bind="totalPrice"></span>
</div>
    
Distribution of Complexity

Break complex tasks into simple steps.

Turn this:
$('#products > li > input').on('change', function(){
  if($(this).is('checked'))
  {
    $(this).parent().addClass('selected');
  } else {
    $(this).parent().removeClass('selected');
  }
  var total = 0;
  $('#products > li.selected > span.productPrice').each(function(){
    total += (1 * $(this).text());
  });
  $('#totalPrice').text(total);
}
    
Distribution of Complexity

Break complex tasks into simple steps.

Into this:
function ViewModel()
{
  ...
  this.totalPrice = ko.computed(function(){
    var total = 0;
    ko.utils.arrayForeach(this.products(), function(product){
      if(product.selected())
        total += product.price;
    });
    return total;
  });
}
    
Makes Unit Testing Simple

By seperating the js from the html, using JSSpec (used by knockout js), QUnit, or xUnit becomes extreamly easy.

Simplify dynamic JavaScript UIs by applying the Model-View-View Model (MVVM) - knockoutjs.com
Say goodbye to jquery!
Say goodbye to r@zor!
Do it all cleaner with

KnockoutJS

MVVM with

KnockoutJS

Getting started:

Include knockout:
<script type="text/javascript" src="~/path/to/knockout-2.2.0.js"></script>
    
Create a ViewModel:
var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);
 
    this.fullName = ko.computed(function() {
        // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
        return this.firstName() + " " + this.lastName();
    }, this);
};
    
MVVM with

KnockoutJS

Bind your data:
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"> \</span>!</h2>
    
Apply your bindings:
ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work
    

First name:

Last name:

Hello, Planet Earth!

MVVM with

KnockoutJS

Using arrays:

Source code: View
<h4>People</h4> <button data-bind="click: addPerson">Add</button>
<ul data-bind="foreach: people">
    <li>
        Name at position <span data-bind="text: $index"></span>:
        <span data-bind="text: name"></span>
        <a href="#" data-bind="click: $parent.removePerson">Remove</a>
    </li>
</ul>
MVVM with

KnockoutJS

Source code: View model
function AppViewModel() {
    var self = this;
 
    self.people = ko.observableArray([
        { name: 'Bert' },
        { name: 'Charles' },
        { name: 'Denise' }
    ]);
 
    self.addPerson = function() {
        self.people.push({ name: "New at " + new Date() });
    };
 
    self.removePerson = function() {
        self.people.remove(this);
    }
}
 
ko.applyBindings(new AppViewModel());

People

  • Name at position 0: Bert Remove
  • Name at position 1: Charles Remove
  • Name at position 2: Denise Remove
MVVM with

KnockoutJS

Integration with C#

Using the mapping plugin you can automatically convert JS objects into knockout observables. Combine this with signalR or ajax to send your c# ViewModels directly to knockout.
MVVM with

KnockoutJS

Knockout Mappping Plugin:

Include script header:
<script type="text/javascript" src="~/path/to/knockout-mapping.js"></script>
    
Recieve data and convert to observable:
var viewModel = ko.mapping.fromJS(data);
    
Recieve data and update the observable:
ko.mapping.fromJS(data, viewModel);
    
Send data back to the server:
var unmapped = ko.mapping.toJS(viewModel);
    
MVVM with

KnockoutJS

More Information:

Documentation (click links on left)
Tutorial

Use a spacebar or arrow keys to navigate