Home | Projects | Tutorials | Articles | live chat | Submit Project | Big Vote
 
Ajax Projects
.NET Frameworks
Java Frameworks
PHP Frameworks
Ruby Frameworks
Other Frameworks
Cool AJAX sites
Ajax Resources
Ajax Tools
JavaScript frameworks

 Home /  Tutorials / Live Data Binding in ASP.NET AJAX 4.0

Live Data Binding in ASP.NET AJAX 4.0





Recently I moved into a new office and went through the extremely pleasant and gratifying experience of packing up all the programming books I had collected in more than 10 years.

Read The Full Tutorial.
































Recently I moved into a new office and went through the extremely pleasant and gratifying experience of packing up all the programming books I had collected in more than 10 years.

Those books could tell you quite clearly how Web programming evolved in the past decade, and which technologies followed one another, each improving (and in many cases revolutionizing) the other.

One book in particular caught my attention. It covered cutting-edge (well, for that era) programming techniques for Internet Explorer 4. I couldn’t resist the temptation to flip through its pages.

In the late 1990s, most big names in the computer industry were engaged in their first attempts to make the Web and the browser a dynamic and highly programmable environment.

Data binding was just one of many popular features being researched and developed. While the basic idea of data binding hasn’t changed significantly over the years, a real transformation did occur as far as its application to the Web world. The common approach to implementing data binding over the Web is radically different today than in the late 1990s, and much of the difference is due to Asynchronous JavaScript and XML (AJAX).

In this column I’ll discuss various forms of client-side data binding as they are coming out in ASP.NET AJAX 4.0. In particular, I’ll focus on some advanced features of data binding and observable objects.

Read more: MSDN

Basic Principles

Generally speaking, data binding is simply
a program’s ability to bind some members of a target component to the
members of a data source. Rapid Application Development (RAD) tools
such as Microsoft Access and Microsoft Visual Basic made data binding a
successful reality.

RAD tools offered an easy and effective
infrastructure for developers to bind visual elements to the members of
a data source. For a long time, the data source was uniquely identified
with a record-set data stream originating from a SQL query.

In
this regard, data binding nicely fits in a smart-client scenario but
poses additional issues if employed in a Web-client scenario. For
example, how would you flow records from the origin database server
down to the requesting JavaScript-equipped browser?

Among many
other things, that old book I opened up after years of oblivion
discussed the data binding features of IE4 based on a couple of special
ActiveX components, aptly named the Tabular Data Control (TDC) and
Remote Data Services (RDS) control. Figure 1
illustrates the overall architecture of client-side data binding as it
was envisioned by IE4 architects in the beginning of the dynamic Web
era.

Figure 1 Client-Side Data Binding in Internet Explorer 4

 A
made-to-measure ActiveX control manages the connection with a remote
data source and takes care of downloading (and optionally caching)
data. The data source is any ODBC-compliant data source with RDS; it’s
a server-side text file with TDC.

The actual binding between
source and target elements is implemented through browser-specific HTML
attributes such as datasrc, datafld and dataformatas. Here’s a quick
example:

<span id="Label1" datasrc="#rdsCustomers" datafld="CompanyName" />

The content of the bound field—CompanyName in the
example—takes up the space reserved for the SPAN tag in the resulting
Document Object Model (DOM).

What does the actual job of
inserting data into the DOM? As mentioned, it’s the browser that in
this case does the trick. When the browser encounters any dataXXX
attributes, it queries the data source control for data using an
internal, contracted API. Any data it gets is then inserted into the
final DOM and displayed to the user.

As you can see, the solution is strongly browser-specific and understandably never captured the heart of developers.

Client-side
data binding was then set aside for a few years as ASP.NET and its
server-side programming model gained wide acceptance.

In recent
years, the advent of AJAX generated a lot of interest around
client-side data binding, and engineers were back at work finding an
effective (and this time cross-browser) way to make it happen.
Evolution in ASP.NET AJAX

Figure 2 shows the overall architecture of client-side data binding as it’s implemented in ASP.NET AJAX 4.0.

Figure 2 Client-Side Data Binding in ASP.NET AJAX 4.0

Although the architectures depicted in Figure 1 and Figure 2 may look similar at first glance, they actually differ in a number of key aspects.

First
and foremost, with ASP.NET AJAX 4.0 you can build client-side
data-binding solutions that work with any modern browser. The glue code
required to actually bind source data to target elements is now part of
the Microsoft Ajax JavaScript library. As such, it can be hosted in any
browser.

Furthermore, for binding you no longer have proprietary
and non-standard HTML attributes such as datasrc and datafld that the
browser must resolve. Instead, binding information is specified using
XHTML-compliant, namespaced custom attributes resolved by code in the
JavaScript library. It can also be done imperatively.
Old-Style versus New-Style

Another
significant difference lies in the structure of the data source object.
In old-style data binding, you use a sort of black-box proxy that
manages data retrieval for you. In ASP.NET AJAX 4.0, you don’t need any
such ActiveX or binary components. All you need is a JavaScript object
with the source data.

The built-in binding infrastructure links together fields on the JavaScript source object and elements of the DOM.

In
ASP.NET AJAX 4.0, such a binding infrastructure is built into the
Sys.UI.DataView component. Functionally speaking, the DataView object
operates in much the same way as the RDS control does in IE4-style
client data binding. It connects directly to a remote endpoint to get
and expose data.

However, there are some differences. The
DataView object is a client control entirely written in JavaScript that
requires no special support from the browser to run. As you can see,
it’s quite different from the RDS ActiveX control.

Moreover, the
DataView control doesn’t directly interface with a relational data
source. Instead, it connects to any JavaScript Object Notation (JSON)-
or JSON With Padding (JSONP)-enabled service, such as a Windows
Communication Foundation endpoint, and exchanges data using JSON. The
service can wrap any physical data store (including a relational
database) or even be a plain wrapper around an Entity Framework model.
As Figure 2 illustrates, in ASP.NET AJAX 4.0 you can even have data
binding in place without an outbound network connection to the server.
If, say, upon loading, a page downloads some data onto the client
machine, you can have data binding at work on locally cached data
without any further roundtrip to the server.
A Brief Summary

In the October 2009 installment of the Cutting Edge column (msdn.microsoft.com/magazine/ee309508.aspx),
I covered the basics of data binding in ASP.NET AJAX 4.0 from a
developer’s perspective. While you can still refer to that article for
deep coverage, I’m going to provide here a brief summary of the most
important programming facts for client data binding.

In ASP.NET
AJAX 4.0, client-side data binding can occur within a proper HTML
template. A template is a DOM tree decorated with the sys-template CSS
attribute:

<div sys:attach="dataview1" class="sys-template">  <br />   ...<br /></div>

The sys-template is a conventional name for a user-defined CSS style that at the very minimum includes the following:

<style type="text/css"><br />   .sys-template { display:none; }<br /></style>

Decorating a given HTML tag with the sys-template attribute
is not enough, however. You must also add some behavior to the tag that
enables it to process any binding expressions inside. In this context,
a behavior is just an instance of a made-to-measure JavaScript
component or control.

A behavior can be attached to an HTML tag,
either by instantiating the behavior programmatically or by using a
declarative approach (by adding markup to the template tags in the
page). For the declarative approach, the behavior must be associated
with a public name (namespace prefix).

Here’s an example of assigning a public name to an instance of the DataView component:

<body xmlns:sys="javascript:Sys" <br />      xmlns:dataview1="javascript:Sys.UI.DataView"><br />...<br /></body>

The sys:attach attribute gets a public name and creates an
instance of the referenced behavior object. In the first code example
in this section, the DIV tag is empowered with the behavior expressed
by the object named dataview1. As you can guess, dataview1 is just the
public name of the Sys.UI.DataView JavaScript object.

Once a
DataView instance has been attached to an ASP.NET AJAX 4.0 template,
the DataView can successfully process any binding expressions contained
in the templates. Here’s a sample template with the simplest binding
syntax:

<ul id="imageListView" class="sys-template" <br />     sys:attach="dataview1"
    dataview1:data="{{ imageArray }}"><br />    <li><br />        <span>{{ Name }}</span><br />        <span>{{ Description }}</span><br />    </li><br /></ul>

The {{expression}} token tells the DataView to process the
embedded JavaScript expression and assign the result to the DOM or the
specified DataView property. For example, the code above assigns the
content of a JavaScript variable named imageArray to a DataView
property named data. In this way, you define the data source of the
binding operation. This information is used to expand any other binding
expressions within the template, such as those used above in the body
of the two SPAN tags. Name and Description are expected to be public
properties on the data item or items assigned to the data property of
the DataView.
Inline Expression Evaluation

The
{{expression}} syntax indicates the simplest type of binding supported
by ASP.NET AJAX 4.0. Any bindings expressed in this way are evaluated
only when the template is rendered. They are never updated unless the
template is refreshed programmatically.

An inline expression is
evaluated against the current state of the data source at rendering
time, but doesn’t automatically capture any further changes made to the
data source.

An alternative, richer binding model is also
supported that gives you the same programming power of XAML data
binding in Windows Presentation Foundation and Silverlight
applications. Such a set of advanced data binding features are commonly
referred to as live binding. Let’s find out more.
Live Binding

Live
binding ensures that the value displayed in the user interface is
automatically updated any time the bound value in the data source
changes. For example, suppose you establish a live binding between a
SPAN tag and the CompanyName property in a data source. The SPAN tag
displays the current value of the CompanyName property at the time of
rendering. However, the content of the SPAN tag will be automatically
updated any time the bound data source property undergoes changes. Live
binding can be applied to any two objects, whether DOM elements or
JavaScript objects.

A different syntax is required for live binding expressions. Here’s an example:

<span>{binding CompanyName}</span>

You use a single pair of curly brackets to wrap the
expression, and prefix it with the keyword binding. As you can see, the
overall syntax has much in common with the equivalent XAML syntax, and
that isn’t coincidental.

It should be noted that the content of
the SPAN tag shown earlier is updated whenever a change is detected on
the currently bound data item; the reverse won’t work. If the content
of the SPAN is updated, that change won’t be propagated to the source
object.

Live binding also can be described as a one-way binding that may happen repeatedly as updates on the data source are detected.

Hold
on! The strategy employed to detect changes on bindings is a key point
and I’ll have more to say about it in a moment, but not before
introducing two-way binding.
Two-Way Data Binding

Two-way
data binding is a special form of live binding that uses two channels
to detect changes on the binding. When two-way binding is in place
between two objects, the following happens:

    * If the data source changes, the target object is automatically refreshed.
    * If the target object changes, the new state is propagated to the underlying data source.

Put another way, two-way data binding ensures that the source and target objects are always in sync.
No Tier Crossing

The
following may perhaps sound like a foregone conclusion, but let me make
it clear anyway. Imagine you have two-way binding between a piece of
user interface and some data that a service retrieved from a database.

The
data downloaded from the server and bound to the visual elements of the
user interface represent a snapshot of the domain model. Say, for
example, it represents a Customer object. If the displayed Customer
object is modified in a two-way binding page, then all detected changes
are mirrored to the client-side Customer object, but in no way will
they be propagated to the server. Two-way data binding doesn’t cross
any tiers.

In terms of syntax, two-way binding is nearly the same as one-way live binding.

An
ASP.NET AJAX binding is expressed via a Sys.Binding JavaScript object.
You can control the direction of the data flow through the mode
attribute on the Sys.Binding object that the framework creates for you
any time you use the live binding syntax. (Note that no Sys.Binding
object is created when you opt for plain {{…}} inline expressions.)

The following code snippet shows how to set up two-way data binding using the mode attribute:

<span id="Label1">{binding CompanyName, mode=twoWay}></span>

Possible values for the mode attribute are summarized in Figure 3.

Figure 3 The Sys.BindingMode Enumeration
Live Binding in Action

Figure 4
shows sample code that demonstrates live, two-way data binding. The
page contains one template that is rendered using a DataView control.
The data source object is a JavaScript array named theCustomers. Don’t
be fooled by the fact that theCustomers is a local object statically
defined within the client browser. What really matters is that
theCustomers is ultimately assigned to the data property of the
DataView object. The DataView object has a rich programming interface
that allows you to put into the data property any content, including
content downloaded from a Web service.

<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="PH_Head"><br />  <br />    <link rel="stylesheet" type="text/css" <br />      href="../../Css/lessantique.css" /><br />    <style type="text/css"><br />        .sys-template { display:none; }<br />    </style><br />    <br />    <script type="text/javascript"><br />        var theCustomers = [<br />           { ID: "ALFKI", CompanyName: <br />            "Alfred Futterkiste" },<br />           { ID: "CONTS", CompanyName: <br />           "Contoso" }<br />        ];<br />    </script><br /></asp:Content>    <br /><br /><asp:Content ID="Content5" <br />  ContentPlaceHolderID="PH_Body" <br />  runat="server"><br /><br />    <asp:ScriptManagerProxy  <br />    runat="server"><br />        <Scripts><br />          <asp:ScriptReference Path=<br />"http://ajax.microsoft.com/ajax/beta/0910/MicrosoftAjaxTemplates.js" /><br />        </Scripts><br />    </asp:ScriptManagerProxy><br /><br />    <div id="customerList"><br />       <ul class="sys-template" <br />         sys:attach="dataview" dataview:data="{{ theCustomers }}"><br />         <li><br />           <span><b>{binding ID}</b></span><br />           <input type="text" id="TextBox1" <br />             value="{binding CompanyName}" /> <br />           <br />  <br />           <span>Currently displaying... <br /><b>{binding CompanyName}</b></span>  <br />         </li><br />       </ul><br />    </div><br /></asp:Content>

Figure 4 Live, Two-Way Binding Sample

For
each bound data item, the template emits an LI tag that includes a text
box. The text box is bound to the CompanyName property of the source.
In the same template, a SPAN tag is also bound to the CompanyName
property of the source.

Note that live bindings are not limited
to the template they belong to. You can have the same expression—say,
{binding CompanyName}—in two different templates. As long as the same
data source object (or a compatible object) is attached to both
templates, the binding will always be correctly resolved. Figure 5 shows the page in action.

Figure 5 Live Binding in Action

Initially
the text box and the SPAN tag contain the same data. However, at some
point the user may start editing the name of the company in the text
box. Nothing happens until the user tabs out of the text box.

The
editing phase is considered complete as soon as the text box loses
focus. At this point, the two-way data binding mechanism triggers and
updates the underlying data source object. Because the SPAN tag is also
bound to the same data property through live binding, any changes are
propagated.

To prevent the automatic update of the data source
when an INPUT element is involved, you set the mode property
explicitly, as shown below:

<input type="text" value="{binding CompanyName, mode=oneWay}" />

Enter this change to the code in Figure 4 and see the difference.
Detecting Changes

When the mode property of a binding is not set explicitly, it takes the auto value as described in Figure 3.
So when you attach a binding to any HTML elements that refer to input
scenarios (such as INPUT, SELECT or TEXTAREA), the property mode
defaults to twoWay. As a result, all the changes to the target made via
the browser’s user interface are automatically transferred to the
source.

Note that there are two variations of a oneWay binding.
The standard oneWay binding detects changes in the source and reflects
them in the user interface. The alternate oneWayToSource does the
reverse: it detects changes in the target and reflects them in the
source object. Try using the following code:

<input type="text" value="{binding CompanyName, mode=oneWayToSource}" />

The initial display of the page will contain empty text
boxes. As you type, though, the new text is detected and processed as
expected.

The two-way data binding option is also the default
option for any bound JavaScript object that happens to implement the
Sys.INotifyPropertyChange interface. (The interface is part of the
Microsoft Ajax JavaScript library.)

When I first introduced live
binding, I said that the target is updated whenever the source changes.
The following explains which changes the framework can detect and how.

HTML
input elements fire standard events when their state is changed or, at
a minimum, they notify when they enter or exit an editing phase.
Because these events are part of the HTML standard, any data binding
solution based on that standard will work on any browsers.

For an
update to one side of the binding to be reflected in the other, it has
to be done in a way that is possible to detect. Suppose you have a
binding where the source is a JavaScript array, as shown here:

<ul class="sys-template" sys:attach="dataview" <br />    dataview:data="{{ theCustomers }}"><br />  <li><br />     <span ><b>{binding CompanyName}</b></span><br />  </li><br /></ul>

Try to update the CompanyName property on an object within
the array. The markup shows a button that if clicked runs the
enterChanges JavaScript function, shown here:

<span>{binding CompanyName}</span><br /><input type="button" value="Enter changes" <br />onclick="enterChanges()" /><br />...<br /><script type="text/javascript"><br />    function enterChanges() {<br />        theCustomers[0].CompanyName = <br />       "This is a new name";<br />    }<br /></script>

The enterChanges function updates the CompanyName property on
the first object in the array. As you can see, this clearly is an
operation that updates the state of a bound object.

In the case
of live binding, you should expect the SPAN tag to display the new
value. If you try that, though, you will see that nothing happens.

That
is because there is no cross-browser way to be notified of updates
occurring to a plain old JavaScript object such as that. So changes
happen but the binding isn’t aware of them and the user interface isn’t
refreshed.

Would polling the state of a plain JavaScript object


be a viable solution? Probably not, and the development team reasonably
ruled out that option, essentially for scalability reasons.

In
the end, is using input HTML elements bound to data the only
possibility for making data changes in a way that will successfully
trigger other live bindings? Well, not exactly. The Microsoft Ajax
JavaScript library features a static API through which you can
“observe” the changes of any JavaScript object. This API is also
available in a flavor that transforms a plain JavaScript object into an
observable object for the binding machinery to detect updates.


Observable JavaScript Objects

An


observable JavaScript object is an object endowed with additional
functionality that raises change notifications when modified.
Additional functionality is codified through the Sys.Observer
interface. Note that changes made directly, without going through the
interface, will not raise change notifications and will be ignored by
the binding infrastructure.

Observable objects fit perfectly in a
scenario where you want to establish live bindings between visual
elements and JavaScript objects, such as those you might get from a
remote Web service.

There are two ways to work with observable


objects. One entails that you make a given object observable by adding
some dynamic code to it—not enough to make a plain JavaScript object a
complex thing, but enough to add new capabilities. Here is an example:

<script type="text/javascript"><br />    var theCustomers = [<br />            { ID: "ALFKI", CompanyName: <br />            "Alfred Futterkiste" },<br />            { ID: "CONTS", CompanyName: <br />            "Contoso" }<br />        ];    <br />    function pageLoad() {<br />        Sys.Observer.makeObservable(theCustomers);<br />    }<br />    <br />    function onInsert() {<br />        var newCustomer = { ID: "ANYNA", <br />        CompanyName: "AnyNameThatWorks Inc" };<br />        theCustomers.add(newCustomer);<br />    }<br /></script>

The Sys.Observer.makeObservable method takes a JavaScript
object (including arrays) and adds methods to it that you can use to
make changes to the object that the bindings can detect. Note that
having an observable array provides methods for changing the array in
an observable way—so you can detect insertions and deletions. But it
does not automatically provide the corresponding methods for modifying
the properties of the individual items in the array in an observable
way. For that, you can separately call makeObservable on the individual
items, and they will then also have additional methods added.

 As I mentioned earlier, the following code associated with a click event won’t trigger the binding:

<script type="text/javascript"><br />    function enterChanges() {<br />        theCustomers[0].CompanyName = <br />        "This is a new name";<br />    }<br /></script>

This code, however, will trigger the binding:

<script type="text/javascript"><br />    function enterChanges() {<br />       System.Observer.setValue(theCustomers[0], <br />       "CompanyName", "New name");<br />    }<br /></script>

What if the observed object has child objects? No worries: the setValue method knows how to handle the “dotted” syntax:

System.Observer.setValue(theCustomers[0], "Company.Address.City", "Rome");

Finally, note that the observer pattern can be applied to any
object you may encounter in the context of a Web page, including DOM
elements, behaviors and even browser objects such as window.


Static and Dynamic

Most
times when you need data binding in an application, you also need it to
be live, at least one-way, if not two-way. In ASP.NET AJAX 4.0, data
binding can be both static—that is, a simple inline evaluation of data
values during rendering—and dynamic, in the sense that it can detect
changes in source or target and apply them.Not all updates can be
detected and used to refresh bindings. ASP.NET AJAX 4.0 easily
recognizes changes entered into bound objects through visual elements.
But for changes entered programmatically into JavaScript objects or
arrays, there’s no reliable cross-browser way to have live detection of
changes. The trick in ASP.NET AJAX consists of providing a way to make
changes so that they’re observable and thus can be detected by live
bindings. This takes the form of appending some observable operations
to the object or, as an alternative, using ad hoc Sys.Observer static
methods to conduct updates.  

source: jasper22.wordpress

 

AddThis Social Bookmark Button
Top Projects
MSN Web Messenger
MessengerFX
ebuddy
e-messenger
ILoveIM
You Tube
AJAX file upload
KoolIM.com
Meebo
Ajax.NET Professional
Tutorials
Simple AJAX is getting advanced
Ajaxian Featured Tutorial: JavaScript Basics
Digg-like Ajax Voting
Building Ajax form with jQuery
ASP.NET Multiple Selection DropDownList with AJAX HoverMenuExtender
Style missing from AjaxToolkit Tab Container
Bundled and Ordered Asynchronous AJAX
Submit multiple forms with jQuery and Ajax
Quick & Easy image rollovers using jQuery
Ruby Basics