Click here to Skip to main content
Click here to Skip to main content

Knockout Tutorial - Part 1

, 13 Aug 2013
Rate this:
Please Sign up or sign in to vote.
Basics of knockout and MVVM pattern

Introduction

In recent years, there’s a lot happening in client side development and popularity of new technologies and frameworks has been taking off.

Many frameworks like angular, backbone, ember, knockouts have come up.

In this series, we would learn about knockout.js and its integration with other client side technologies. In Part 1, we would cover the following :

  • What is Knockout (KO)
  • MVVM Pattern
  • Scenario

Knockout

Knockout is a JavaScript library that helps to create rich, responsive display and editor user interfaces with a clean underlying data model.
It is a JavaScript implementation of the Model-View-ViewModel pattern with templates.

Let’s try to understand about MVVM pattern which Knockout uses for binding HTML element with view model.

MVVM

What is MVVM

It is a software architectural pattern.

It was originally defined by Microsoft to be used with WPF and Silverlight. It is an extension of Martin Fowlers ‘Presentation pattern





What kind of Pattern

It is one of the presentation patterns. The basic purposes of these patterns are to remove complication around UI development and make it easy for development, clean and manageable code. MVP, MVC are the other presentation patterns. data binding between View and view model makes it different from other presentation Patterns.

Conceptual Diagram

Conceptual Diagram

M in MVVM

M is model. Model is responsible for:
  • State management
  • Business Logic
  • Data access: It may be from different data sources like web services, database, etc.

An example of Model can be an Account object with the following properties:

  • Bank Name
  • Account Number
  • Status

V in MVVM

The view is an application user interface which defines the appearance of UI using different elements and control like textbook, buttons, combo box, image, etc. The view is responsible for rendering UI elements.

VM in MVVM

VM stands for VIEW MODEL
  • Its agent for between Model (M) and View(V) which glues them together.
  • Its “Model of the view” and exposes its properties, commands and abstraction to view.
  • The VM retrieves data from the model (M) and exposes it to the view (V) as properties in a form that the view can easily consume.
So far, we discuss what is MVVM. Let's see how it's getting realized in different technologies.

Realization in WPF

Realization uing WPF

Realization in HTML/JavaScript (Using Knockout.js)

Realization using Knockout.js

All theoretical so far. Let’s do some coding using Knockout.

Coding

What we are going to cover here:
  • Problem Statement
  • Implementation without Knockout
  • Implementation with Knockout

Problem Statement

Let's take a simple case to display User’s Account information like Bank, AccountNumber, Status on page.

Implementation Without Knockout

What we would need to implement it:

  1. HTML Elements for BankName, Account Number and status
  2. JavaScript for defining Account class and object
  3. JavaScript/Jquery to search HTML elements and pushing data to them

User Interface

    <body>
      <h2>My Account </h2>
        <span>Bank Name:</span><span id="accontBankName"></span>
        <br />
        <span>Account Number:</span><span id="accountNum"></span>
        <br />
        <span>Account Type:</span><span id="accountType"></span>
        <br />
        <span>Status:</span><span id="accountStatus"></span>
    </body>   

JavaScript Code

    <script src="jquery/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">

        $(document).ready(function () {
            function Account(bank, accNo, type, status) {
                var self = this;
                self.bank = bank;
                self.accNo = accNo;
                self.type = type;
                self.status = status;
            };
            var myAcc = new Account("Bank1", "12345678", "Saving", "Active");
            // To add this
            $("#accontBankName").text(myAcc.bank);
            $("#accountNum").text(myAcc.accNo);
            $("#accountType").text(myAcc.type);
            $("#accountStatus").text(myAcc.status);
        });
    </script>   

Let’s see what could be the possible issues with the above approach:

  • Requires a line of code for each mapping between source value and target elements. Just think the case where we would have had many more elements.
  • If source value changes, we would have to write more code to push the values again.
  • If the value changes in the HTML element, the changes would not be reflected in the underlying source.

Point 2 and Point 3 can be resolved with a lot of coding. But would it not be better if we have some framework which does this and binds HTML elements with the source object. This is where a framework like knockout comes into the picture.

Implementation using Knockout

    <body>
      <h2>My Account </h2>
        <span>Bank Name:</span>< 
        data-bind="text: account.bank" span id="accontBankName"></span>
        <br />
        <span>Account Number:</span>< 
        data-bind="text: account.accNo" span id="accountNum"></span>
        <br />
        <span>Account Type:</span>< 
        data-bind="text: account.type" span id="accountType"></span>
        <br />
        <span>Status:</span>< 
        data-bind="text: account.status"  span id="accountStatus"></span>
    </body>   

Changes are highlighted with blue background. Data-bind attributes comes from knockout library and use to bind element with object properties.

A binding consists of two items, the binding name and value, separated by a colon

JavaScript Code

    <script src="jquery/jquery.min.js" type="text/javascript"></script>
    <script src="ko/knockout-2.3.0.js"></script>
    <script type="text/javascript">

        $(document).ready(function () {
            function Account(bank, accNo, type, status) {
                var self = this;
                self.bank = bank;
                self.accNo = accNo;
                self.type = type;
                self.status = status;
            };
             function AccountViewModel() {
                var self = this;
                self.account = new Account("sbi", "12345678", "Saving", "Active");
            };
            ko.applyBindings(new AccountViewModel());

        });
    </script>   

Changes are highlighted with blue background

  • Script to include knockout.js. You can download from here.
  • Create AccountViewModel class :- the class to bind with UI elements.
  • Ko.applybinding :- it activate the KO and sets the data context for the page to the AccountViewModel object.
As you see, it reduces the number of lines of code. As the number of properties and elements increase, only the JavaScript codes which may require to change the applyBindings function. It fixes the issue# 1 we highlighted in our approach without knockout.

Let’s see how to fix issue #2 i.e. sync data between source object and html element. Here Observables from KO would help. Observables Are special JavaScript objects that can notify subscribers about changes, and can automatically detect dependencies.
How to make object property observable?

Using ko. Observable ()

Let's see how the code would look like now.

JavaScript Code

    <script src="jquery/jquery.min.js" 
      type="text/javascript"></script>
    <script src="ko/knockout-2.3.0.js"></script>
    <script type="text/javascript">

        $(document).ready(function () {
            function Account(bank, accNo, type, status) {
                var self = this;
                self.bank = bank;
                self.accNo = accNo;
                self.type = type;
               self.status = ko.observable(status);
            };
             function AccountViewModel() {
                var self = this;
                self.account = new Account("sbi", 
                "12345678", "Saving", "Active");
            };
            ko.applyBindings(new AccountViewModel());
        });
    </script>   

To see how it syncs data, let's add one input element and bind it to status property. Now we have two elements which are bind to status property.

  1. span element with id=accountStatus
  2. Input elements

Here the UI code would look like:

    <body>
      <h2>My Account </h2>
        <span>Bank Name:</span>
        <span data-bind="text: account.bank" 
        span id="accontBankName"></span>
        <br />
        <span>Account Number:</span>
        <span data-bind="text: account.accNo" 
        span id="accountNum"></span>
        <br />
        <span>Account Type:</span>
        <span data-bind="text: account.type" 
        span id="accountType"></span>
        <br />
        <span>Status:</span><
        span data-bind="text: account.status"  
        span id="accountStatus"></span>
        <p>Change Account status 
        <input data-bind="value:account.status" /></p>
    </body>   

Browse the page with the latest changes. You would see the following screen:

Type Closed in input box:

Click outside of input box. You would see:

When you changed the value in input box, it updates the status property its bind to. As the same property binds to span displaying status, it changes value displayed in span to "Closed".

Summary

In this article, we covered the basic on Knockout and MVVM. There are many things to cover like observable array, computed properties, command binding and conditional binding. We would continue our discussion in the next article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

deepak gupta07
Architect
India India
No Biography provided

Comments and Discussions

 
QuestionTo the point and simple. Pinmemberrenu.iitkgp28-Apr-14 23:36 
GeneralMy vote of 3 Pinmembershrikanth.tm2-Apr-14 17:16 
QuestionGodo job PinmemberSaurabh Nayar3-Oct-13 2:47 
QuestionOccur one confusion for your javascript code PinmemberTridip Bhattacharjee14-Aug-13 1:55 
AnswerRe: Occur one confusion for your javascript code Pinmemberdeepak_gupta0714-Aug-13 2:13 
GeneralRe: Occur one confusion for your javascript code PinmemberTridip Bhattacharjee14-Aug-13 8:54 
GeneralRe: Occur one confusion for your javascript code Pinmemberabhijit shah18-Aug-13 23:59 
GeneralMy vote of 3 PingroupAkhil_Mittal13-Aug-13 23:33 
GeneralMy vote of 5 PinmemberPaulo Zemek13-Aug-13 16:12 
GeneralRe: My vote of 5 Pinmemberdeepak_gupta0713-Aug-13 18:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 14 Aug 2013
Article Copyright 2013 by deepak gupta07
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid