My fingers are itching for doing something “real” with Knockout so I will start with a small application for collecting and presenting resources here on my blog. I’m listening to a lot of podcasts and from each I get a lot of links that I want to present on a page.

What I want is this:

  • A page that presents a list of tags and a list of resources
  • On selecting one or multiple tags a filtered list of resources will be displayed
  • A resource will contain a URL, a description, date added, tags
  • A small administration interface to add and edit resources
I have previously gone through the tutorials at http://learn.knockoutjs.com and I also have a lot of blog posts saved in Evernote. For this first part I looked at http://wakeupandcode.com/getting-started-with-knockoutjs-and-mvvm/.

If you install ASP.NET and Web Tools 2012.2 you will get a Single Page Application, SPA, template in Visual Studio 2012. You can read more about it here.
There’s a sample application, a ToDo list, created in that template and it’s pretty nifty. For now I feel like I’m jumping ahead doing this so I’m keeping the sample application project open as a reference but will start with an empty project for my Resource application.

I created an ASP.NET MVC4 Web API project. Since I have the SPA project in the same solution I already have the Nuget package for Knockout. If you don’t you can use the Visual Studio Nuget manager to install Knockout, Tools/Library Package Manager/Manage Nuget Packages for Solution. There’s a lot of stuff in this template as well but right now I want to get going so this will do.

Ok, let’s start with Knockout, that’s what I want to learn so the server stuff I’ll take later. 🙂

First I need a viewmodel so I can bind my data to the interface. I need two objects: Resource and Tag and a viewmodel to hold them together.

function Tag(name) {
    var self = this;
    self.name = ko.observable(name);
}

function Resource(url, description, dateadded, tags) {
    var self = this;
    self.url = url;
    self.description = description;
    self.dateadded = dateadded;
    self.tags = tags;
}

function ResourcesViewModel() {
    var self = this;

    self.tags = [
        { name: "tag1" },
        { name: "tag2" },
        { name: "tag3" }
    ];

    self.resources = ko.observableArray([
        new Resource( "url1", "description 1" , "2013-08-22" , "tag1, tag2"),
        new Resource( "url2", "description 2" , "2013-08-22" , "tag2, tag3")
    ]);
}
ko.applyBindings(new ResourcesViewModel());

I put some boring static data in my model so I can test my data binding. Now I need to set up my web page.

My user interface is very simple to start with. I need a list of clickable tags and a list for resources and some databinding for those lists (more about the data items below).

<ol data-bind="foreach: tags">
    <li >
        <span data-bind="text:name"></ span>
    </li >
</ol>
<table>
    <thead ><tr>
        <th> Resource</th ><th> URL</ th><th >Date</ th><th >Tags</ th>
    </tr ></thead>
    <tbody data-bind ="foreach: resources">
        <tr>
            <td data-bind="text: description"></ td>
            <td data-bind="text: url"></ td>
            <td data-bind="text: dateadded"></ td>
            <td data-bind="text: tags"></ td>
        </tr>
    </tbody >
</table>

I need Knockout to be included in my page and looking at the SPA solution I noticed that I can include the Knockout scripts and my application specific scripts like this:

@section scripts {
    @Scripts .Render( "~/bundles/knockout")
    @Scripts .Render( "~/bundles/resources")
}

and in the _Layout.cshtml file there’s

@ RenderSection("scripts" , required: false)

This is made possible by a bundle configuration file in the App_Start folder.

public static void RegisterBundles( BundleCollection bundles)
{
    bundles.Add( new ScriptBundle ("~/bundles/knockout" ).Include(
            "~/Scripts/knockout-{version}.js" ));
    bundles.Add( new ScriptBundle("~/bundles/resources" ).Include(
            "~/Scripts/app/resource.viewmodel.js" ));
}

And in the Global.asax.cs file I found

BundleConfig .RegisterBundles(BundleTable .Bundles);

Bundling is a new feature in ASP.NET 4.5 that allow you to combine multiple files into a single file. You can read more about it here.

I should be able to runt this now and at least get my small initial lists displayed.

Wow, it actually works! It’s not beautiful but it’s a working Knockout interface and I’m totally happy. I have a viewmodel with data and I’m displaying it on the screen.

In the next part I want to be able to filter the resource list by clicking one or multiple buttons in the tag list. I also want to get the data from the ASP.NET Web API.

The source code can be found at https://github.com/PDahlen/OneHourADay/tree/master/OHaD.Resources

Advertisements