Starting out with KnockOut JS–Don’t do it without WebMatrix

So far all my development was using Silverlight. Now that Microsoft officially killed (I know, I know and lets not go there) Silverlight, we started looking at future alternatives. One of the task was to look at knockout JS. One of the reason was as a Silverlight developer who enjoys MVVM pattern, I should be able to adapt to it fast. So in this blog I am not going to talk about how to do things in Knockout JS, rather the tools you need to have to get started.

One thing I really I love about Knockout JS is, amount of documents available for newbie like me to get started. First of the links that you must have

The mother ship is @ Knockout JS. In my opinion you will not need anything else. This has fantastic starter tutorials, excellent documents. I wish every one creates web site like this some day. One another site you need to have in your bookmark if you decide to develop is Knock me out. This blog lots of tips and tools that is going to make your coding life so easy.

There are two forums that you can get answers from. Google groups and of course Stack overflow. In my opinion, I would recommend you guys to use Google Forums, I seem to get more response there than stack over flow. Oh by the way, I asked one question on Stack overflow, guess who answered, John Papa himself. I was so happy to see, John Papa is on Knockout camp. I will come to that in a minute.

Ok development environment. So you decided to start testing and play around with Knockout JS. One thing you need to think about is, how are you planning to develop the app. As you all know, I am more inclined to Microsoft IDEs so I am going to talk about only MS IDEs. You could develop Knockout sites using ASP.Net MVC templates. You will end up using ASP.Net features inter mingled with Knock out. I wanted to learn Knockout with out the noises of other technologies and focus purely on Knockout. I still want ease of development and of course intellisense. I came across Web Matrix day before yesterday and I fell in love immediately. Please remember to download the beta (2/18/12) It is so easy to develop and file based operation make it easy to drag and drop files and make it available to the solution etc., One good thing is if you want to develop ASP.Net MVC model you can develop it in there also, if you want to develop pure HTML model, you can do that also, that is what drawn me to this. So if you are setting up environment like me

1. Download Web Matrix Beta.

2. Download Knockout JS

3. Download jQuery js.

4. Download knock out mapping. (If you plan to do JSON)

Now that you have all in place, lets start building our first knock out code. Fire up Web matrix

image

In here, click on templates and create an empty site as shown below, name the site as HelloWorld

image

Now the site is created and it will take you a page something like

image

Please make sure you have downloaded knockout JS (KO) (step 2 of the download). Now click on the Files option on bottom left hand side

image

which will toggle the top left hand side to show the files instead of site.

image

First thing I do, is to create Scripts folder, where I am going to house all my scripts. So right click on the HelloWorld and create a new folder

image

call it Scripts. Next, open the Script folder so that you can copy knockout js that you have downloaded. One thing, I need to point out here, there is no solution or project model that we used to in Visual Studio. If a file is available in the directory structure then the file is available to use. So the idea here is that, if you want a file added to script, all you have to do is drop the file in Scripts folder. So, to do that, right click on Scripts folder and make it show the folder in windows explorer. Now copy KO js into the folder from your download directory. If you copied the file and if it does not show up in the web matrix view, make sure you right click on the directory and do ‘Refresh’. That’s is it, now we have the environment setup to write the code.

image

We could write the Hello world like java script model all in view, but we are doing knock out, so lets do it like we do it in MVVM, we will use binding to show Hello World. We are going to create a view model and setup a property which will have a string value of Hello World which is what we are going to bind in the view to show hello world. So do that, we click on Scripts folder and add a new java script file called ViewModel.js

image

image

Paste the code from below to make your view model java script

   1:  /// <reference file="knockout-2.0.0.js" />
   2:   
   3:  function ViewModel() {
   4:      var self = this;
   5:      self.helloWorld = "Hello World";
   6:  };
   7:   
   8:  var viewModel;
   9:   
  10:  function init(){
  11:      this.viewModel = new ViewModel();
  12:      ko.applyBindings(viewModel);
  13:  }
 

1 –> it is a required line, you add the reference to the javascript library so that web matrix can give you intellisense. If you do not have this line, then line 12, when you type ko. it will not show available methods.

3-6 –> This is our view model. Here we have one property called helloWorld which has ‘Hello World’ string assigned to it.

8 –> define the view model variable to be used in binding.

10-13 –> This is a very important method. This is required if you would want to separate the view and view model separate. You will see in a minute, this method is called on html body load so that, view model is created and also all the ko binding are applied as well.

Now lets look at our view. For our view, I am using the default.cshtml file.

   1: <!DOCTYPE html>

   2: <script src="Scripts/knockout-2.0.0.js" type="text/javascript"></script>
   1:  

   2: <script src="Scripts/ViewModel.js" type="text/javascript">

</script>

   3: <html lang="en">

   4:     <head>

   5:         <meta charset="utf-8" />

   6:         <title></title>

   7:     </head>

   8:     <body onload="init()">

   9:         <p><span data-bind="text: helloWorld"></span></p>

  10:     </body>

  11: </html>

2 –> references the ko js library and viewmodel java script.

8 –> instantiate the view model on the html load.

9 –> binds the helloWorld property of the view model to the DOM element.

That’s all folks. There is a clear separation of view and view model. Not only there is separation, this allows us to do unit testing of view model easy.

Few points to remember;

1. Make sure every html tag have associated end tag. If you do not, the ko will not come around and inject the code for you. I had a code like

<strong data-bind=”text: helloWorld”/> <—– this will not work.

<strong data-bind=”text: helloWorld”></strong> <— this works.

2. When using web matrix, in your view model, add reference to all the js library you are using so that web matrix can help you with intellisense.

3. I like web matrix model of developing KO application since, it is file based, I can just copy files without dependencies and is pure HTML/JS development. But if you choose to develop using ASP.Net MVC, that is also build into it.

Working with Grid SelectedItems without any line of code in code behind

This is another blog related to creating clean separation of View and ViewModel. When you use Grid and have to act on a single selected item, just pass ‘SelectedItem’ in the command parameter. What happens when you need to act with multiple rows, it is also as simple as using SelectedItems in the command parameter. With this you do not need to write anything in the code behind, especially navigate through the collection of selected items to publish the result to ViewModel. I do not like this idea of coding in code behind in this scenario, especially you are exposing the model to the view when you are boxing individual elements. If you would expose the Model to View then you are breaking the fundamental MVVM pattern. Fortunately we can achieve this without any line of code in the code behind.

XAML

<Button Content="Selected Items" Command="{Binding SelectedItemsCmd}" CommandParameter="{Binding ElementName=grid, Path=SelectedItems}" Grid.Column="1" />
 <c1:C1FlexGrid Name="grid" ItemsSource="{Binding Rows}" AutoGenerateColumns="True" Grid.ColumnSpan="2" Grid.Row="1" />

In XAML binding, we say we are going to execute ‘SelectedItemsCmd’ which takes all Selected Items from the grid as the parameter.

ViewModel

 

public IActionCommand<object> SelectedItemsCmd { get; set; }

        public void SelectedItemsTest(object parameter)
        {
            List<string> temp = new List<string>();
            foreach(var item  in (IList)parameter)
            {
                temp.Add(item.ToString());
            }
        }

 

I am using Jounce as my MVVM framework and Component One for my grid control. Component One returns IList of objects. So in my case, the data binding happens to be List<string> so I walk through the returned object collection and cast each object the I need to box and I use it in my View Model. Thanks to Bernardo @ Component One for help clarify IList for me.

Design Time Data in Silverlight

Recently I read an outstanding article on MVVM by Ward Bell. If haven’t read it, please go back and read it. If you don’t read it for technical aspect, read it for the way he wrote it. It was well written and have excellent content. I really like the way, he took apart the MVVM and looked at it from completely opposite side of it. I totally agree with him on the two points that he finished his article on.

1. MVVM gives good design time data.

2. Unit testing of VM.

I have been coding heavily in SL for some time now. I was developing application using MVVM from day one, but and I need to confess here, I did not do either of the items so far. I completely ignored (1) and troubled a lot with (2). Finally I gave up both the items and developed application in MVVM for easy maintenance and scalability.  After reading the article I realized, I am completely wasting a great feature SL for design time data. So I thought, I will create a simple application and show and learn how to do design time data.

Like all my application, I always starts with Jounce. If you have not looked at Jounce, I would highly recommend it. If you have any problem using Jounce, you can contact me and I will see if I can find answer for you, if not, you can always post the question in Jounce Codeplex. Hopefully you have already installed Jounce Template, if not you will find the VS2010 template at the bottom of the Jounce Ccodeplex page. So now that we have all the required items, lets start rolling.

Start VS2010 and create a brand new Jounce Application. Build the application and run it. yes, do not change anything, just compile and run it. it is supposed to build with out any errors and will display a browser window with ‘Welcome to Jounce’ message. Ok now that we got the basic program running and before we make any changes, lets look at the solution structure.

image

I did not change anything, this is the default structure. In here, you will see four folders.

Common: Interface for main view model.

Jounce: location of jounce reference dll.

SampleData: Lets put a pin here and we will come back here since it is our point of interest.

ViewModel: As the name suggests, it is the view model class.

Now, lets open XAML, it will look something like the following

image

If you see in the design screen, there is a text block which have a text block that shows “This is some design-time text.”. If you look at the XAML, the text block does not have the value. So how and where did it get it? Before I answer that question, lets look at the binding. There are two types of binding, yes, I know, I did not know this either. They are design time binding and run time binding. All the binding we have done so far is run time binding. We create a binding to a control, we run the application and see the data bound to the control, which is run time binding. On the other hand, the design time binding as the name suggests, will bind the data to the control during design time so that you can see the control how it looks. This is extremely useful, if you have designer working along with developer using expression blend to create front end UI for you. There are two important content in the XAML which did design time binding for you.

image

The first green box, establishes the xml namespace for our sample class. The second box did the design time data binding. By default, when you want to use design time data binding, you create a xml namespace pointing to blend and mark it as mc:Ignorable. The later part is to make sure XAML parser will not complain if there is a XAML parse error on design time. Lets look at the d:DataContext in the Grid. what we are saying here, is that for design time data binding, the data comes from an instance of DesignMainViewModel of name space desfined as sampleData. Also create an instance if it is not available. It is very straight forward.

Now lets look at the DesignMainViewModel class.

using System;
using JounceAppWithDesignDataAndTesting.Common;

namespace JounceAppWithDesignDataAndTesting.SampleData
{
    public class DesignMainViewModel : IMainViewModel
    {
        public string WelcomeText
        {
            get { return "This is some design-time text."; }
        }
    }
}

if you look at this, it is a very simple class, which implements IMainViewModel interface and yes, it is the data that we see in XAML design page.

namespace JounceAppWithDesignDataAndTesting.Common
{
    public interface IMainViewModel
    {
        string WelcomeText { get; }
    }
}

If you remember when you run the application the result will be something like this

image

Now where did this message comes from. Well, we did not see the run time, that is the view model implementation.

using System;
using Jounce.Core.ViewModel;
using JounceAppWithDesignDataAndTesting.Common;

namespace JounceAppWithDesignDataAndTesting.ViewModel
{
    [ExportAsViewModel("MainViewModel")]
    public class MainViewModel : BaseViewModel, IMainViewModel
    {
        public string WelcomeText
        {
            get { return "Welcome to Jounce."; }
        }
    }
}

As you can see, the WelcomeTtext return "Welcome to Jounce." during run time and that is what get bound to the text block. So the bottom line is;

1. Create an interface so that all data bound values are available during design time.

2. Create Design time view model which returns dummy data based off of the interface defined in step 1.

3. Make sure, implement the interface in the view model.

4. In XAML make sure design name spaces are defined and then bind the grid to the design time instance.

In this example, I did not make any changes to the default project since Jounce by itself creates the design time binding structure for us and that we can leverage for next examples. I will take an attempt at one more design time data binding and then go to Unit testing in Silverlight.

If any of you have any questions or comments, I would love to hear from you.