December 13th, 2012

Knockout Intellisense in ASP.NET and Web Tools 2012.2 RC

WTE (Web Tools Extension) 1.2 RC is part of the ASP.NET and Web Tools 2012.2 RC and it’s available for download from http://www.microsoft.com/download/details.aspx?id=36053.

Knockout Intellisense is an exciting new feature in WTE 1.2 RC.  Knockout is a declarative JavaScript MVVM system for client-side data binding.  See http://knockoutjs.com/ for complete information and http://learn.knockoutjs.com/ for tutorials. 
Knockout Intellisense allows you to code Knockout quickly and accurately, and custom bindings are fully supported!

With WTE 1.2 RC installed, you can utilize the Knockout Intellisense feature on any web page by:

  • Loading Knockout-n.n.n.js or Knockout-n.n.n.debug.js
  • Defining a view model in JavaScript as an object or a function
  • Calling ko.applyBindings(viewModel) after the page is loaded

Loading Knockout

Add Knockout to an existing project by selecting “Manage Nuget Packages…”:

Search online for “Knockout” and select “Knockoutjs”:

Press “Install”

Drag the Knockout JavaScript file from Scripts to the head of your web page:

Note: to use Knockout with Bundling and Minification, see the “Working with Bundling and Minification” topic below.

Knockout does not require jQuery, but the two work great together.

Defining a View Model

A view model can be defined in one of two ways; see http://knockoutjs.com/ for complete details.

Declare the data structure you want to use as a JavaScript object:

    <script>
      var viewModel = {
        fieldOne: “string”,
        fieldTwo: 12345,
        fieldThree: null,
        fieldFour: ko.observable(“two way data-binding”),
        fieldFive: ko.observableArray([1,2,3])
      };
    </script>

 Or, declare a function with members describing your data:

    <script>
      function viewModel() {
        this.detailsEnabled = ko.observable(false);
          this.enableDetails = function () {
            this.detailsEnabled(true);
          };
          this.disableDetails = function () {
            this.detailsEnabled(false);
          };
      };
    </script>

Applying Bindings

If you’ve described your view model as an object, bind itusing the syntax:

    ko.applyBindings(viewModel);

If you’ve declared your view model as a function, use the syntax:

    ko.applyBindings(new viewModel());

Note: In either case, it’s critical to bind the view model after the page data has been loaded.  You can do this by either declaring a script block at the end of the page:

    …
    <script>
      …
      ko.applyBindings(viewModel);
    </script>
    </body>
    </html>

Or by applying the binding in a jQuery document.ready function or similar method:

    <script>
      $(function () {
        function viewModel() {
          …
        }
        ko.applyBindings(new viewModel());
      });
    </script>

Using Knockout Intellisense

Once you’ve defined and applied your view model, you are ready to work with Knockout Intellisense. 
Add a data binding to an HTML element by using the new “db” snippet.

Place your cursor in an opening HTML tag, type <space>db<tab><tab> and get:

   

Next, begin typing the name of a binding (custom bindings
are fully supported) and a completion list will appear:

   

Complete your binding with a colon. Press Control-J or Control-Space if you’d like to see a full list of available values; applicable values will appear automatically once you start typing:

   

Note that Knockout bindings are highlighted to make them stand out on a page:

   

Working with Bundling and Minification

To add Knockout to an existing project utilizing bundling and minification, such as an application created from the ASP.NET Web Forms Application template:

  • Add the Knockoutjs package to the project as described above
  • Open the file Scripts_references.js and drag Knockout-n.n.n.js onto the document window.  This will add a script reference definition:
    /// <reference path=”knockout-2.2.0.js” />
  • While you have _references.js open, ensure that your jQuery and other file names exactly match the installed file names.  If you have updated packages, these may be out of sync and you will not benefit from accurate Intellisense.
  • Open App_StartBundleConfig.css and add the following to the function “RegisterBundles”:
       bundles.Add(new ScriptBundle(“~/bundles/knockout”).Include(“~/Scripts/knockout-*”));
  • In an asp:PlaceHolder in the head of the master page, add:
        <%: Scripts.Render(“~/bundles/knockout”) %>
  • Remember to declare your view model and call ko.applyBindings after your page is loaded.

Caveats

Bindings for “foreach”, “with” and template

Three special bindings, “foreach”, “with” and “template”, are not correctly implemented in WTE 1.2 RC.

The “foreach” and “with” bindings should each establish a binding context, such that values within the context should refer to nested bindings. In the RC, the top-level context is used within the binding context rather than the nested context, so values presented in the value completion list are invalid.
This is a known RC issue and will be fixed in RTM.

Variables such as $parent and $data will not point to the correct contextual object for Intellisense.  Of course, these features work normally at runtime.

The “template” binding should not show a list of values from the view model at all; rather, it uses an object which describes a named template and its associated data.  In the RC, “template” displays an ordinary top-level context value list, which is invalid.
This is a known RC issue and will be fixed in RTM.

Containerless Control Flow Syntax

The “if”, “ifnot”, “foreach” and “with” bindings can be expressed in containerless flow control comments, like:

    <!– ko foreach: myItems –>
    <li>Item <span data-bind=”text: $data”></span></li>
    <!– /ko –>

WTE 1.2 RC does not evaluate these comments and they are ignored.  Again, “foreach” and “with” do not establish binding contexts in this case and so the values in the value completion list will be invalid.
This is a known RC issue and will be fixed in RTM.

SPA Application Template

WTE 1.2 RC comes with a new MVC4 application template, theSingle Page Application:

   

This template makes extensive use of Knockout in Views/Home/Index.cshtml.  However, most of the binding expressions are nested with a binding context established by a “foreach” binding, so the value Intellisense provided is invalid.  (See the earlier caveat.) 
This is a known RC issue and will be fixed in RTM.

Troubleshooting

If you get no colorization of Knockout binding expressions, then the Knockout-n.n.n.js file was not found among the scripts or references.  Double check the “Loading Knockout” instructions above.

If you get colorization and binding name Intellisense, but not value Intellisense, then the ko.applyBindings call was not found, which establishes the view model to use.  Double check the “Defining a view Model” instructions above.

If you’re having trouble with Bundling and Minification, more information is available at http://go.microsoft.com/fwlink/?LinkId=254726.

If you see the following values in the value completion list rather than the view model values that you expect:

   

…then you have declared your view model as a function, but called
    ko.applyBindings(viewModel)
instead of
    ko.applyBindings(new viewModel())
You are not the first.  🙂

 

 

Author

0 comments

Discussion are closed.