You are here:   Blog
Register   |  Login

LightSwitch News

Why I Love Office 365
9/29/2014 12:07 PM

 

Dec 12

Written by: Michael Washington
12/12/2012 7:02 AM  RssIcon

 

LightSwitch JavaScript Data Binding

 

In the LightSwitch HTML Client Preview 2, the binding pattern has several advantages in that it allows you to create large robust and well structured applications. You may have heard about the binding pattern in Silverlight and WPF (known as MVVM). The key component is the INotifyPropertyChanged interface that raises an event when anything changes a property that implements the interface.

 

image

The ability to simply bind to a property (this can be a single scalar value or an entity composed of several properties) allows you to simply subscribe to changes in say the First Name property, and in one place, validate, update, or persist the value in one or more centralized methods. Without binding, you would need to implement if… then code in a multitude of places potentially creating spaghetti code (the larger you application gets).

 

Binding in JavaScript

You can find a good overview of frameworks that allow binding in JavaScript at this link. What the link does not cover is all the work that you must do to implement the frameworks. Knockout is a popular JavaScript binding framework, and its Hello World requires 10 lines of code, consisting of a integrated View and a View Model that you must carefully craft (without making any typos). I created an implementation for the article A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page. What I learned from that experience was a deeper appreciation for the C# code behind experience Smile. When you don’t have a compiler, every line of code you write comes at a price that grows exponentially the larger your application gets. The key is to write as little JavaScript as possible (and to also use tools such as TypeScript (see: Creating JavaScript Using TypeScript in Visual Studio LightSwitch)).

Also, see Stephen Provine’s comments at this link as to reasons why LightSwitch does not use Knockout (but you still can implement Knockout yourself manually).

 

Binding In The LightSwitch HTML Client

image

To see a detailed example of JavaScript binding in the Visual Studio LightSwitch HTML Client, see: Implementing The Wijmo Radial Gauge In The LightSwitch HTML Client. The binding part comes down to only three lines:

 

    contentItem.dataBind("value", function (newValue) {
        UpdateRadialContrl(radialContrl, newValue);
    });    

 

The remaining binding code is automatically done for you by the Visual Studio code designer and the Visual Studio LightSwitch runtime. LightSwitch is a productive liberating tool.  LightSwitch is the easy to use tool to create great modern software.

image

To illustrate how data binding works in LightSwitch, we will start with the example program created in: Using Toastr with Visual Studio LightSwitch HTML Client (Preview).

 

Two Methods To Bind Them All

Two methods to bind to data will be explored, dataBind and addChangeListener. dataBind is a function that actually implements addChangeListener. dataBind provides the advantage in that it parses the input binding path that you specify, and creates change notifications (using addChangeListener). Each change notification will raise the callback function that you specify in the  dataBind constructor. addChangeListener on the other hand, will just bind to the element that you specify. addChangeListener has the advantage, that unlike dataBind, does not require a contentItem (so it can be used in entity code that does not have a contentItem).

 

dataBind

image

A nice feature about LightSwitch is that it allows you to easily see what you are binding to. To bind to data, you click on the element you want to bind to in the screen designer.

image

In the Properties for the element, you can click Edit postRender Code.

image

This will take you to a JavaScript method that is wired-up and ready for your custom code.

We will start off by just displaying the initial values, using the Toastr JavaScript plug-in, by adding the following code to the method:

 

    // Display Initial Values
    var FirstName = contentItem.value.FirstName;
    var LastName = contentItem.value.LastName;
    var InitialValues = 'Initial Values:'
                            + ' FirstName = '
                            + FirstName
                            + ' LastName = '
                            + LastName;
    toastr.info(InitialValues);   

 

image

When we run the application the initial values are displayed.

However, when we change the values, to see the new values, we have to save the record and re-open it.

To resolve this, and provide the INotifyPropertyChanged like binding notifications, we use the following code:

 

        // Binding to only the FirstName property
        contentItem.dataBind("value.FirstName", function (newValue) {
            var newFirstName = newValue;
            var updatedFirstNameOnly = 'Updated FirstNameOnly: '
                                        + newFirstName;
            toastr.info(updatedFirstNameOnly);
        });

 

image

The diagram above shows how the data flows.

You will also notice that code was added around the binding, because in this example the binding is in a Dialog popup box. The View Model (that is automatically created for you by LightSwitch) is re-used each time the Dialog box is opened. Without some sort of flag like hookedEvents we would have multiple bindings attached each time the Dialog is opened.

Note, the flag code would not be needed if you had a separate page for editing that was completely closed and re-opened each time (see: Implementing The Wijmo Radial Gauge In The LightSwitch HTML Client for an example).

image

Also, note that the initial scope is the entire People entity (that consists of FirstName and LastName), but in this case we are only binding to the FirstName property (because we set dataBind binding to “value.FirstName”).

 

image

When we run the application, the Toastr notification will show the latest value each time we change it (and tab out of the box).

The following code shows how to bind to the property that indicates if a property is “dirty” (has been changed):

 

        // Binding to LastName isChanged property
        contentItem.dataBind("value.details.properties.LastName.isChanged", function (newValue) {
            var isChangedLastName = 'LastName.isChanged: '
                                        + newValue;
            toastr.info(isChangedLastName);
        });

 

image

When we run the application, we can see the value change.

 

When and Where to use it

Use it within a render or postRender function, this allows you to easily get notified when some property (that is reachable from the contentItem) has changed, regardless of how deeply nested the data is.

Limitations

dataBind requires a contentItem and you don’t have that  in a Screen or Entity method (however, in a Screen method, you can use code like: contentItem = screen.findContentItem("OrderDate") to get a specific content item).

 

addChangeListener

image

We can open a table (entity).

 

image

When we select the Client tab, the Write Code menu will allow access to the created method.

 

image

Unlike the render methods, we only have access to entity, therefore we must use addChangeListener.

 

Add the following code:

 

    entity.addChangeListener("LastName", function (e) {
        toastr.info("(from entity level) LastName value changed to: " + entity.LastName);
    });

 

 

image

When we run the application, we have to create a new entity to invoke the addChangeListner.

 

image

The notification will fire without the need to save the record first.

 

When and Where to use it

Use it from within Entity and Screen functions. This code would work anywhere you show the data (avoiding the need to duplicate the logic on each screen the data objects appears on).

 

Limitations

It does not have the ability to specify a binding path to listen to nested data.

 

LightSwitch Help Website Articles

Implementing The Wijmo Radial Gauge In The LightSwitch HTML Client

Writing JavaScript In LightSwitch HTML Client Preview

Creating JavaScript Using TypeScript in Visual Studio LightSwitch

Theming Your LightSwitch Website Using JQuery ThemeRoller

Using Toastr with Visual Studio LightSwitch HTML Client (Preview)

 

LightSwitch Team HTML and JavaScript Articles

Custom Controls and Data Binding in the LightSwitch HTML Client (Joe Binder)

Creating Screens with the LightSwitch HTML Client (Joe Binder)

The LightSwitch HTML Client: An Architectural Overview (Stephen Provine)

Writing JavaScript Code in LightSwitch (Joe Binder)

New LightSwitch HTML Client APIs (Stephen Provine)

A New API for LightSwitch Server Interaction: The ServerApplicationContext

Building a LightSwitch HTML Client: eBay Daily Deals (Andy Kung)

 

 

Special Thanks

A special thanks to LightSwitch team member Stephen Provine for his valuable assistance.

 

Download Code

The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx

(you must have HTML Client Preview 2 or higher installed to run the code)

2 comment(s) so far...


Gravatar

Re: Writing JavaScript That Implements The Binding Pattern In Visual Studio LightSwitch

Nice article, but how does one know that "value.details.properties.LastName.isChanged" even exists? I.e. how does one explore or know about this hierarchy? Thanks.

By dan houck on   2/22/2014 5:43 AM
Gravatar

Re: Writing JavaScript That Implements The Binding Pattern In Visual Studio LightSwitch

If you search the Microsoft site there is documentation.

By Michael Washington on   2/22/2014 5:44 AM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 

Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation