Ever wonder what Knockout JS is? Since it’s going to be a part of the default ASP.NET template in VS2012 I figured that I should take a look. AND what better project to try something new in than Nerd Dinner. The Popular Dinners list in the Home/Index view is already using jQuery to get JSON data and dynamically building the list, this seems like the perfect candidate to refactor to use knockout.

Nerd Dinner 1

The first step in adding Knockout to NuGet (assuming that you already have the latest Nerd Dinner source) is to get the package from NuGet

Nerd Dinner 1

First, I need to add a script reference to knockout in the _Layout.cshtml

<script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>

Next, the code in the Index.cshtml view needs to be changed from the empty container that gets dynamically populated to the use a knockout template. So I changed this line:

<div class="entry-content" id="dinnerList"></div>

to

<ul class="entry-content" id="dinnerList" data-bind="foreach: dinners">
  <li class="dinnerItem">
    <a data-bind="attr: { href: Url }, text: Title"></a>
        <br />
        &amp;lt;strong data-bind=&amp;quot;dateString: EventDate, datePattern: &#039;mmm d&#039;&amp;quot;&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;span data-bind=&amp;quot;rsvpMessage: RSVPCount&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;<br />
  &amp;lt;/li&amp;gt;<br />
&amp;lt;/ul&amp;gt;

Similarly, in the NerdDinner.js file _renderDinners needs to be changed to use knockout model binding. After some code cleanup _renderDinners now looks like this:

NerdDinner._renderDinners = function (dinners) {
    var viewModel = {
        dinners: ko.observableArray(dinners)
    };
    ko.applyBindings(viewModel);

<pre><code>NerdDinner.ClearMap();

$.each(dinners, function (i, dinner) {
    var LL = new VELatLong(dinner.Latitude, dinner.Longitude, 0, null);

    // Add Pin to Map
    NerdDinner.LoadPin(LL, _getDinnerLinkHTML(dinner), _getDinnerDescriptionHTML(dinner), false);

    // Display the event&amp;amp;#039;s pin-bubble on hover.
    var dinnerPin = _getDinnerPin(dinner.DinnerID);
    if (dinnerPin != null) {
        $(dinner).hover(
            function () { NerdDinner._map.ShowInfoBox(dinnerPin); },
            function () { NerdDinner._map.HideInfoBox(dinnerPin); }
        );
    }
});

// Adjust zoom to display all the pins we just added.
if (NerdDinner._points.length &amp;amp;gt; 1) {
    NerdDinner._map.SetMapView(NerdDinner._points);
}
</code></pre>

};

Next, there were some custom binders that I needed to add. One for displaying the EventDate properly and another for showing the RSVP Message. They look like this at the end of the NerdDinner.js file:

ko.bindingHandlers.dateString = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();
        var allBindings = allBindingsAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        var pattern = allBindings.datePattern || 'MM/dd/yyyy';
        var v1 = eval('new' + valueUnwrapped.replace(///g, ' '));
        var v2 = v1.format(pattern);
        $(element).text(v2);
    }
};
ko.bindingHandlers.rsvpMessage = {
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        var rsvpMessage = &quot; with &quot; + value + &quot; RSVP&quot;;
        if (value &gt; 1)
            rsvpMessage += &quot;s&quot;;
        $(element).text(rsvpMessage);
    }
};

Finally, This sample has just barely scratched the surface of the interesting things that knockout allows you to do. If you’re interested in learning more go the Knockout JS site. Also, the Nerd Dinner source is on Codeplex. I’d encourage you to get it, fork it, and make it better!

Leave a Reply

I’m Peter

I’ve spent my career building software and leading engineering teams. I started as a developer and architect, grew into engineering leadership, and today I serve as a Chief Technology Officer.

Here, I share practical insights on technology, leadership, and building high-performing teams.

Connect with me on LinkedIn.

Discover more from Peter Mourfield

Subscribe now to keep reading and get access to the full archive.

Continue reading