ASP.NET AJAX Templates

Switch View :
ScriptFree
ASP.NET AJAX Templates

[This documentation is for preview only, and is subject to change in later releases. Blank topics are included as placeholders.]

ASP.NET AJAX templates simplify the process of creating a dynamic data-driven user interface (UI) in the browser. Templates let you specify the UI for data controls by using HTML markup. The UI is rendered dynamically in the browser, and it can respond automatically to changes in the data on the client without requiring any request or postback to the server. You can create dynamic pages such as master-detail views that render data from a Web service or an ADO.NET data service, using little or no JavaScript code.

You can use ASP.NET AJAX templates in ASP.NET Web pages, in HTML pages, or in any other type of endpoint that renders HTML in the browser.

This topic contains the following sections:

Prerequisites for Using ASP.NET AJAX Templates

In order to use ASP.NET AJAX templates in an ASP.NET Web page, a Web application must target version 4 of the .NET Framework. The Web page should include a script reference to the MicrosoftAjaxTemplates.js library, as in the following example:

<asp:ScriptManager ID="sm" runat="server">
  <Scripts>
    <asp:ScriptReference Name="MicrosoftAjaxTemplates.js" />
  </Scripts>
</asp:ScriptManager>

To use ASP.NET AJAX templates in an HTML page (or an MVC view), you must first obtain the static script files for the ASP.NET 4 AJAX Framework, such as the latest ASP.NET AJAX Preview release. For more information, see the ASP.NET AJAX Web site.

Your page should then include script elements that reference the MicrosoftAjax and MicrosoftAjaxTemplates script libraries, as in the following example:

<script type="text/javascript" src="MicrosoftAjax.debug.js"></script>
<script type="text/javascript" 
    src="MicrosoftAjaxTemplates.debug.js"></script>

Note Note

Alternatively, you can use release versions of these script libraries, such as MicrosoftAjax.js.

Rendering Client Templates

In client-based development, templates are the most manageable way of creating UI from data. ASP.NET AJAX includes a template engine for client development that meets the following requirements:

  • Performance. The engine can render a typical number of items using a reasonably complex template before users perceive an interruption in their interaction with the application.

  • Simplicity. The template syntax is easily readable and is optimized for the most common scenario, namely one-way, one-time binding.

  • Power. The template syntax supports live binding, including two-way binding between UI elements and the fields of the underlying data objects.

  • Expression language. Templates support an expression language that goes beyond the simplest cases. The expression language uses familiar syntax.

  • Interspersed code and markup. It is possible to perform conditional rendering or to loop over markup by using code that surrounds HTML.

  • XHTML compliance. Templates can render XHTML-compliant markup (although this is not be mandatory).

  • Components. When you use the template syntax, you can instantiate controls and behavior that attach to HTML elements in the page or within templates.

Template Example

The following example shows a typical client template that you can create using ASP.NET AJAX.

<ul id="myTemplate" class="sys-template">
  <li>
    <h3>{{ Name }}</h3>
    <div>{{ Description }}</div>
  </li>
</ul>

The class attribute of the outer div element is set to sys-template, which is a convention that is used in order to hide the initial template from the user. By convention, you define this class in the page's CSS style sheet as {display:none;}.

When the template is rendered, it has a data item as context. Fields or properties of that data item can be included in the template markup by using {{ }} expressions. For example, you can use {{ Name }} if the data item has a Name field. These expressions can be included anywhere in text content, or you can use them as the value of an attribute. In addition to referencing fields or properties, the expression blocks can contain any JavaScript expression that can be evaluated as a string.

You can also include live binding. In the following example, the value of the text box input control is bound to the Name field of the dataItem object by using live two-way binding. The inner text of the span element is bound to the same field by live one-way binding. When the user changes the name in the text box, the title (the inner text of the span element) is automatically updated.

<div id="detailView" class="sys-template">
  <!--Live binding onewWay-->
  <span class="detailtitle">{binding Name}</span>
  <!--Live binding twoWay-->
  <input type="text" sys:value="{binding Name}"/>
</div>

You can also set up DOM events within your template. The DataView class provides a simple way to specify commands by using the sys:command and sys:commandargument attributes, and then handling the command event. The DOM on<event> attributes of elements (for example, onclick="method") also work within templates. In addition, you can use the $addHandler method (for example, in the itemCreated event of the DataView object) to attach event handlers to DOM elements within the template.

Instantiating Controls in Markup and in Code

You can instantiate ASP.NET AJAX client controls either declaratively or in code. When you instantiate a control declaratively, you set properties and fields of the control by setting the attributes of the control directly in the markup. This approach requires less coding and can be easier to read.

When you instantiate a control in code, you use client script to instantiate and initialize the client control, and to associate it with an HTML element.

Instantiating a Template Using the DataView Control

The most common way to use client templates in ASP.NET AJAX is through the DataView control. The content of a DataView control is used as a template that renders the data item that is provided to the control. If you set the DataView control's data property to an array, the template is rendered one time for each item in the array.

The following example shows the declarative markup for a DataView control that binds to an array named imageArray. The sys:attach attribute is used to attach a DataView control to the HTML element that will be the container for the rendered items.

html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Sys.UI.DataView</title>
    <link href="../styles/divList.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjaxTemplates.js"></script>
    <script type="text/javascript">
        var imageArray = [
            { Name: "Crashing water", Description: "A splash of waves captured." },
            { Name: "Dazed", Description: "Mid-day heat?" },
            { Name: "Close Zoom on Giraffe", Description: "Closeup of a Giraffe at Wild Animal Park." },
            { Name: "Pier", Description: "A pier in Morro Bay." },
            { Name: "Seagull reflections", Description: "Seagulls at peace." },
            { Name: "Spain", Description: "In Balboa Park, in downtown San Diego." },
            { Name: "Sumatran Tiger", Description: "Restful." }
        ];
    </script>
</head>
<body xmlns:sys="javascript:Sys"
      xmlns:dataview="javascript:Sys.UI.DataView"
      sys:activate="*">

    <ul id="imageListView" class="list sys-template"
        sys:attach="dataview" 
        dataview:data="{{ imageArray }}"
    >
        <li>
            <span class="name">{{ Name }}</span>
            <span class="value">{{ Description }}</span>
        </li>
    </ul>
</body>
</html>


Instantiating a Template Using Code

The following example shows how to instantiate a DataView control in code. This is equivalent to the declarative markup in the previous example.

$create(
    Sys.UI.DataView,
    {
        data: imageArray
    },
    {},
    {},
    $get("imageListView")
);

For more information see, Walkthrough: Using an ASP.NET AJAX Template.

You can also create a compiled template directly in code by using the Template class, as shown in the following example:

var t = new Sys.UI.Template($get("myTemplate"));

The constructor takes the parent element of the template as its argument. You can then render a compiled template into the DOM by calling its instantiateIn method and specifying an HTML container element and a data item as context. The following example shows how to call the instantiateIn method.

t.instantiateIn(
    $get("targetContainer"), 
    {
        Name: "Name",
        Description: "Description"
    }
);

Using Pseudo-Columns in a Template

In addition to providing access to fields and properties of the dataItem field, the template rendering engine provides access to pre-defined "pseudo-columns" such as $index, $dataItem, $element and $id. These pseudo-columns give you access to values from the rendering engine at render time. You can use pseudo-columns the way you use any JavaScript variable in the template instance.

Expressions and code blocks can use pseudo-columns that are provided to the template engine:

  • $index enables you to access the current index of the item that is being rendered, if the template is being rendered as part of a list.

  • $dataItem enables you to access the current data item.

  • $id ("myId") enables you to create or access an ID value within a template. It makes sure that the actual rendered ID is unique even if the template is repeated for multiple data items in an array.

  • $element enables you to access the preceding element in the template.

The following example shows how to use the $id pseudo-column. Additional examples that are presented later in this topic show examples of the $index, $dataItem and $element pseudo-columns.

<div id="masterView" class="sys-template"
    sys:attach="dataview"
    dataview:data="{{ imageArray }}" 
>
  <div>
    <label for="{{ $id('name') }}">Name: </label>
    <input id="{{ $id('name') }}" 
         type="text" sys:value="{binding Name}"/>
  </div>
</div>

Incorporating Code into a Template Using Attributes

You can add the code:if, code:before, and code:after declarative attributes to any DOM element within a template to render the element conditionally (code:if) or to render arbitrary code before (code:before) or after (code:after) the element. The following example shows how to use the code:If attribute to render an hr element as a separator between items. The code:if attribute uses the value of the $index pseudo-column to make sure that the hr element is rendered only between items, and not before the first item or after the last item.

<ul id="myTemplate" class="sys-template">
  <li>
    <hr code:if="$index!==0" />
    <h3>{{ Name }}</h3>
    <div>{{ Description }}</div>
    <a href="#" sys:codeafter="$addHandler($element, 'click', function() {showDataItem($dataItem);})" >Show Data Item</a><br />
  </li>
</ul>

Instantiating Behaviors and Controls Declaratively

ASP.NET AJAX includes a way to declaratively instantiate controls and behaviors and attach them to HTML elements. The declarative markup does not require any new HTML elements. Instead, it is supported by the addition of some namespaced attributes.

Instantiating Declaratively Inside a Template

To instantiate behaviors or controls declaratively, you start by declaring a namespace prefix in the opening <body> tag, similar to the way the @ Register directive works in server-based files. The following example shows a namespace declaration that you might use if you want to add a Contoso.DatePicker control to a template.

<body xmlns:sys="javascript:Sys" xmlns:datepicker="javascript:Contoso.DatePicker" sys:activate="*">

The javascript:Sys namespace (typically mapped to the sys: prefix, as shown in the example) is used for several system attributes. One of those system attributes is sys:attach, which is used to specify a comma-separated list of controls or behaviors to attach to the element, as shown in the following example:

<ul id="myTemplate" class="sys-template">
  <li>
    <h3>{{ Name }}</h3>
    <div>{{ Description }}</div>
    <div sys:attach="datepicker" datepicker:date="{{ CreatedDate }}"></div>
  </li>
</ul>

The example shows how to instantiate a Contoso.DatePicker control that is attached to a div element and how to set the control's date property to the value of the CreatedDate field of the current data item.

Instantiating Declaratively Outside a Template

You can declaratively instantiate controls only if the declarative markup is within an element that has been configured, or activated, for this purpose. Templates themselves are already activated. Therefore, declarative markup to instantiate and attach controls works within a template.

However, to declaratively instantiate controls outside a template, you must first configure the page to make sure that sys:attach markup is within an activated element. You do this by including a sys:activate attribute on the opening body tag, and setting the value for sys:activate to a comma-separated list of IDs of the elements that you want to enable declarative instantiation in. The following example activates elements whose IDs are panel1 and panel2:

<body xmlns:sys="javascript:Sys" sys:activate="panel1,panel2">

This causes the ASP.NET AJAX framework to scan the children of those elements for any sys:attach attributes, and to instantiate the corresponding controls.

You can also activate every element in the document. However, doing this can cause a small delay when the page is initialized. Therefore, the technique should be used with caution on large pages. The following example shows how to activate the whole document.

<body xmlns:sys="javascript:Sys" sys:activate="*">

A DataView control is typically attached to an element that is not already within a template. This is a common reason to use sys:activate, as in the following complete example:

<body xmlns:sys="javascript:Sys"
    xmlns:dataview="javascript:Sys.UI.DataView"
    sys:activate="*">

  <ul sys:attach="dataview" class="sys-template"
      dataview:data="{{ imagesArray }}"
  >
    <li>
      <h3>{{ Name }}</h3>
      <div>{{ Description }}</div>
    </li>
  </ul>
</body>

Namespace-Qualified Attributes

Namespace-qualified attributes (prefixed attributes) are used in ASP.NET AJAX declarative markup to attach controls, specify data bindings, determine interactive behavior, and also similar operations. ASP.NET AJAX includes the following forms of mapping attributes.

  • System attributes, which map specialized ASP.NET AJAX system attributes, such as sys:activate.

  • HTML attributes, which map HTML attributes so that they are visible to ASP.NET AJAX, such as sys.id.

  • ASP.NET AJAX class attributes, which map an ASP.NET AJAX class so that properties can be declaratively set, such as dataview:autofetch

System Attributes

System attributes use the sys: prefix, which maps to the javascript:Sys namespace URI. The following table summarizes the system attributes.

System Attribute

Description

Example

sys:activate

Used to configure (activate) an element to support declarative instantiation.

<body xmlns:sys="javascript:Sys" sys:activate="panel1,panel2">

or

<body xmlns:sys="javascript:Sys" sys:activate="*">

sys:attach

Used to specify a comma-separated list of controls or behaviors to attach to an element.

<body xmlns:dv="javascript:Sys.UI.DataView">
<ul id="myTemplate" class="sys-template" sys:attach="dv">

sys:command

Used to raise a command event.

<li sys:command="Select">{{ Name }}</li>

sys:commandargument

Used to pass a command argument.

<td sys:command="Sort" sys:commandargument="ProductNumber">Product Number</td>

sys:commandtarget

Used to pass a command to a target.

<td sys:command="Sort" sys:commandtarget="ProductName">

sys:key

Used to create a local JavaScript identifier for an element or a component.

For an element:

<div sys:key="myDiv">Hello World!</div>

For a component:

<div dataview:sys-key="master"

HTML Attributes

HTML attributes specify bindings for HTML attributes. These attributes are like HTML attributes, such as the value attribute of an input tag, but with the sys prefix added, as in sys:value="{binding Name}". The following table provides examples.

HTML Attribute

Description

Example

sys:checked

Used to set the checked state of an HTML element.

<input type="checkbox" sys:checked="{{ isChecked }}" />

sys:disabled

Used to set whether the user can interact with the element.

button onclick="saveChanges()" class="saveButton" sys:disabled="{binding hasChanges, source={{imagesDC}}, convert=not}">Save Changes</button>

sys:id

Used to provide a dynamic id based on the current data item.

<input type="text" sys:id="{{ 'flight' + $index }}" value="{binding flight"}/>

sys:src

Used to set the image source of an image element.

<img sys:src="{{ imageSrc }}"/>

ASP.NET AJAX Class Attributes

ASP.NET AJAX class attributes are used to set the properties on a control or behavior that has been declaratively attached to an HTML element by using sys:attach. The following example shows how to map the Sys.UI.DataView class to the namespace prefix. The dv prefix is used with the sys:attach attribute to instantiate the DataView control and attach it to the ul element. Attributes that use the dv prefix are used to initialize the attached DataView control.

<body xmlns:sys="javascript:Sys"
    xmlns:dv="javascript:Sys.UI.DataView"
    sys:activate="*">

  <ul class="list sys-template"
      sys:attach="dv"
      dv:autofetch="true"
      dv:dataprovider="{{ imageService }}"
      dv:fetchoperation="Images"
  >
    <li>
      <span class="name">{{ Name }}</span>
      <span class="value">{{ Description }}</span>
    </li>
  </ul>
</body>

Data Binding

The following table summarizes the types of data binding that are available in ASP.NET AJAX.

Binding Type

Description

Example

Inline expression evaluation

Provides binding in which the expression that is enclosed in braces is evaluated and inserted as a target value, such as HTML content or the value of an id attribute.

This binding type does not support live binding to a data item. Therefore, the rendered expression is not updated if the underlying data item is modified.

<span>{{ CompanyName }}</span>

or

<div sys:id="{{ $id('name') }}">

Note Note
If the target for expression evaluation of binding is an HTML attribute, the sys: prefix must be added to ensure valid HTML. In some cases this is also required in order to obtain full functionality.

One-way binding

Provides live binding from the fields or properties of the source object (by default, the current data item) to the target value. If the underlying source data item is modified, the rendered value is updated automatically.

One-way binding is the default mode for binding to HTML properties or content, except for the values input controls.

<span>{binding CompanyName}</span>

or

<input type="text"

  sys:value="{binding CompanyName, mode=oneWay}" />

or

<img sys:src="{binding Uri}"/>

Two-way binding

Provides live binding from the fields or properties of the source object (by default the current data item) to the rendered target value, and also from the rendered value back to the source.

If the underlying source data item is modified, the rendered target value is updated automatically. In addition, if the user changes the target value (such as the value of an HTML input control when the control is bound to an underlying source data item), the underlying source is updated.

Two-way binding is the 0default mode for binding to the value property of HTML input controls, and to read-write properties of attached controls, behaviors, and components.

<input type="text"

  sys:value="{binding CompanyName}" />

or

<ul class="sys-template" sys:attach="dataview"

    dataview:selectedindex="{binding selectedIndex, source=nameList}"

One-time binding

Provides binding from the fields or properties of the source object (by default the current data item) to the rendered HTML. Unlike one-way binding, the value is evaluated and inserted into the rendered HTML only when the template is instantiated. There is no live binding to the data item. Therefore, the rendered expression is not updated if the underlying data item is modified.

<span>{binding Price, convert=formatAsDollars, mode=oneTime}</span>

For more information about the DataView control, about data binding and expression evaluation in templates, and about one-way, one-time data binding, see How to: Create a Master-Detail View with Inline Binding Expressions and How to: Create an Editable View with Two-Way Data Binding.

Inline Expression Evaluation

The most common scenario for rendering data values in templates involves inline expression evaluation. The syntax is as follows:

{{ expression }}

An inline expression can be specified in any element attribute, as in the following example:

<input type="text" value="{{ name }}"/>

The expression can appear anywhere in a text node, as in the following example:

Rating: {{ rating }}/5

The expression in a one-way, one-time binding can be an arbitrary JavaScript expression, as in the following example:

Percentage: {{ score / total * 100 }}%

When the expression is evaluated, the fields of the current data object are accessible by name. In the previous examples, name, rating, score and total refer to the fields of the data object.

Using inline expressions to insert data values within a template means that the expression is evaluated only once, at the time that the template is rendered. If the source data changes after the template has been rendered, the rendered value is not updated automatically.

One-Way Binding

To make sure that the target value is automatically updated whenever the source value changes, you can use one-way live-binding syntax, as shown in the following example:

<h3>{binding Name}</h3>

If the Name field of the current source data item changes, the rendered value is automatically updated.

Note Note

The pervious example binds to HTML content, which automatically defaults to one-way binding. This is true for binding to any HTML property except the value property of an input control.

In one-way live binding, there is no binding from the target back to the source.

Two-Way Binding

Two-way live binding is useful when an input control such as a text box lets users modify the value of underlying data. The following example shows the syntax of two-way binding.

<input type="text" sys:value="{binding Name}"/>

Note Note

Because the binding is to the value property of an input control, the binding mode defaults to two-way binding.

In two-way live binding, the binding works in both directions. If the target value is changed in the text box, the source value is automatically updated in the associated source data item. Similarly, if the source value of the underlying data item is updated externally, the target value of the text box is updated in response. As a result, target and source are always in sync.

The following example shows how to use two-way live binding. If the user modifies the value in the text box, the value that is rendered in the h3 element is automatically updated to reflect the new value.

<h3>{{ binding Name }}</h3>
<input type="text" sys:value="{binding Name}"/>

The live-binding syntax is similar to binding syntax in WPF (XAML). It can be used for binding between UI and data, directly between UI elements, between data and properties of declaratively attached controls and components, and in other binding scenarios.

The syntax supports additional features, such as functions that convert between data values and displayed values. The following example shows how to use conversion functions.

<input type="text" value="{binding Price, convert=toDollars, convertBack=fromDollars}"/>

You can use similar syntax to specify a binding mode (one-way or two-way) explicitly:

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

However, in most cases you do not have to include the binding mode, because the default binding behavior for input controls is two-way binding. Bindings to HTML properties or content use one-way binding. In the previous example, the binding expression overrides the default behavior so that if the data value changes, the value in the text box changes. However, if the user modifies the value, the underlying data value is not updated.

Using the Observer Pattern

The technology that enables live bindings is the ASP.NET AJAX observer pattern, which is used internally by the Binding class. The observer pattern enables an object to be notified about changes that occur in another object.

Note Note

The term observer pattern is often misused in JavaScript frameworks to describe event handling based on the addHandler method and similar techniques.

ASP.NET AJAX implements the observer pattern completely. It adds observer functionality to ordinary JavaScript objects or arrays so that they raise change notifications when they are modified by means of the Observer class. In the present state of JavaScript, changes that are made directly, without using the observer functionality, do not raise change notifications. The observer pattern can be used to establish live bindings between UI elements and objects or arrays, such as those you might get from a JSON Web service.

In the following example, the Observer class is used to add items to the imagesArray array in a way that raises notifications that the collection has changed. As a result, the DataView control automatically updates and displays the inserted item after the user has clicked the Insert button. The DataView control handles onCollectionChange notifications for the data that the data property is set to (in this case, the imagesArray array), and refreshes its rendered items whenever it is notified of a change.

<script type="text/javascript">

var imagesArray = [];

Sys.Observer.makeObservable(imageArray);

function onInsert() {

var newImage = { Name: "Name", Description: "Description" };

imagesArray.add(newImage);

}

</script>

<button onclick="onInsert()">Insert</button>

<ul id="imagesList" sys:attach="dataview" class="sys-template"

dataview:data="{{ imagesArray }}"

>

<li>

<h3>{{ Name }}</h3>

<div>{{ Description }}</div>

</li>

</ul>

Using Data Controls and Classes

The most common controls to use when you work with ASP.NET AJAX templates and data are the following:

  • DataView control

  • DataContext class

  • AdoNetServiceProxy class

  • AdoNetDataContext class

This section provides details about how to use these data controls and classes. For more information about ASP.NET AJAX classes, see ASP.NET AJAX Client Reference.

The DataView Control

The DataView control can bind to any JavaScript object or array, or to any ASP.NET AJAX component. 

Note Note

Components derive from the Sys.Component class and typically have no UI representation. For more information about ASP.NET AJAX components and controls, see Creating Client Components and Controls.

Providing Data to the DataView Control

Data can be provided to the DataView control in several ways. You can set the data property of the DataView control. The following example shows how to set the DataView control’s data property through declarative binding:

<ul sys:attach="dataview" class="sys-template"
    dataview:data="{{ imagesArray }}"
>
  <li>
    <h3>{{ Name }}</h3>
    <div>{{ Description }}</div>
  </li>
</ul>

The following example shows how to set the DataView control’s data property by using code:

<script type="text/javascript">
    function pageLoad() {
        imagesService.GetImages(querySucceeded);
    }

    function querySucceeded(result) {
        $find("imagesList").set_data(result);
    }
</script>

<ul id="imagesList" sys:attach="dataview" class="sys-template">
  <li>
     <h3>{{ Name }}</h3>
     <div>{{ Description }}</div>
  </li>
</ul>

You can also specify a WCF or ASP.NET Web service directly in the dataProvider property of the DataView control, as shown in the following example:

<ul sys:attach="dataview" class="sys-template"
    dataview:autofetch="true"
    dataview:dataprovider="../Services/imagesService.svc"
    dataview:fetchOperation="GetImages"
>
  <li>
    <h3>{{ Name }}</h3>
    <div>{{ Description }}</div>
  </li>
</ul>

When the DataView control’s dataProvider property is set, the DataView control uses the provider (in the previous example, the Web service) to fetch data by using the operation that is specified in the fetchOperation property. For other examples in which the dataProvider property is set to an instance of the DataContext class (used for read-write scenarios) see the DataContext class and AdoNetDataContext class later in this topic.

Additional Features of the DataView Control

The DataView control provides several additional features, including the following:

  • Support for layout templates and external templates.

  • Built-in selection support for use in master-detail scenarios.

  • Command bubbling (propagating events to the parent control).

The following example shows how to use some of these features to configure master-detail views, using two DataView controls that are linked through live binding.

<!--Master View-->
<ul sys:attach="dataview" class=" sys-template"
    dataview:autofetch="true"
    dataview:dataprovider="../Services/ImageService.svc"
    dataview:fetchoperation="GetImages"
    dataview:selecteditemclass="myselected" 
    dataview:initialselectedindex="0" 
    dataview:sys-key="master" 
>
  <li sys:command="Select">{binding Name}</li>
</ul>
 
<!--Detail View-->
<div class="sys-template" 
    sys:attach="dataview"
    dataview:data="{binding selectedData, source={{master}} }"
>
  <div>Name: <input type="text" value="{binding Name}"/></div>
  <div>Description: <input type="text" value="{binding Description}"/></div>
</div>

The Select command in the master view template makes sure that when the user clicks an item in the master view, that item becomes the selected item. As a result, the CSS class specified in the selectedItemClass property of the master DataView control is applied to the markup for that item. In addition, the corresponding data item becomes the value that is returned by the selectedData property of the master DataView control.

The detail DataView control uses live binding so that its data item is dynamically set to the current selectedData value of the master DataView control. In the example, the detail view provides an edit template with two-way binding that lets users modify the fields of the data item.

The DataContext Class

For read-write scenarios that use Web services or data services, ASP.NET provides a DataContext class that provides full support for change tracking in the browser. This enables complete end-to-end AJAX-based data scenarios.

Typically, data is fetched from the server through JSON services such as a WCF AJAX-enabled service or through ADO.NET data services. The data is displayed to the user through dynamic data-driven UI, using the DataView control. Declarative live-binding markup in the template provides users with an edit UI, which enables them to modify the data. The ASP.NET AJAX DataContext class tracks changes to the data automatically. All changes can then be sent to the server in a single HTTP request by calling the saveChanges method of the DataContext class. A single DataContext instance can manage change tracking for data returned by different operations on the server, even if the operations return different types of objects.

The following example shows how to use the DataContext class.

<script type="text/javascript">
    var dataContext = new Sys.Data.DataContext();
    dataContext.set_serviceUri("../Services/imagesService.svc");
    dataContext.set_saveOperation("SaveImages");
    dataContext.initialize();
</script>

<button onclick="dataContext.saveChanges()" class="right">Save Changes</button> 

<ul sys:attach="dataview" class="sys-template " 
    dataview:autofetch="true"
    dataview:dataprovider="{{ dataContext }}"
    dataview:fetchoperation="GetImages"
    dataview:fetchparameters="{{ {orderBy: 'Name'} }}"
>
  <li>
    <input type="text" value="{binding Name}"/><br/>
    <input type="text" value="{binding Description}"/>
  </li>
</ul>

The AdoNetServiceProxy Class

The AdoNetServiceProxy class enables read-write interaction with ADO.NET Data Services from JavaScript. The class enables access from JavaScript to a broad range of features of ADO.NET Data Services. The class provides programmatic access to the basic REST operations provided by ADO.NET Data Services (insert, query, update, and remove), as well as to many advanced features such as verb tunneling (custom HTTP methods) and optimistic concurrency.

The AdoNetServiceProxy class provides functions that you can call in order to interact with a data service from an ASP.NET AJAX application. By using this class, you can create Web applications that interact with data from the Web site and that can update the Web page without a full postback to the Web server.

When you create an instance of the AdoNetServiceProxy class, you provide the relative URI of the data service that contains the data that you want to retrieve, as shown in the following example:

var exampleService = 
    new Sys.Data.AdoNetServiceProxy("/northwind.svc");

After you create an instance of the AdoNetServiceProxy class, you can set properties of the class that are used as the default properties in all data operations. These properties include the defaultSucceededCallback and defaultFailedCallback properties, which contain the names of the functions that will be called after the data operation has succeeded or failed. The defaultUserContext property contains the context information that is passed as a parameter to the callback functions, unless you provide a different user context when you call a data operation.

The insert, query, remove, and update methods enable you to perform a single operation. The createActionSequence method enables you to create an AdoNetActionSequence object and add operations to a queue that are executed as a batch. The invoke method enables you to execute a method of the data service. The fetchDeferredProperty method enables you to load data from a property that was not retrieved in the original data request because the property contains a large amount of data.

The following example shows how to use code to instantiate a AdoNetServiceProxy class and use it as the data provider for a DataView object.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Sys.Data.AdoNetServiceProxy</title>
  <link href="../styles/divList.css" rel="stylesheet" type="text/css" />
  <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjax.js"></script>
  <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjaxTemplates.js"></script>
  <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjaxAdoNet.js"></script>
  <script type="text/javascript">
      var imageService = new Sys.Data.AdoNetServiceProxy('../Services/ImagesDataService.svc');
  </script>
</head>

<body xmlns:sys="javascript:Sys"
    xmlns:dataview="javascript:Sys.UI.DataView"
    sys:activate="*">

  <ul class="list sys-template"
      sys:attach="dataview"
      dataview:autofetch="true"
      dataview:dataprovider="{{ imageService }}"
      dataview:fetchoperation="Images"
      dataview:fetchparameters="{{ {$orderby: 'Name'} }}"
  >
    <li>
      <span class="name">{{ Name }}</span>
      <span class="value">{{ Description }}</span>
    </li>
  </ul>
</body>
</html>

For more information about the AdoNetServiceProxy class, see How to: Query a Data Service Using AJAX.

The AdoNetDataContext Class

Typically, data is fetched from the server through JSON services such as a WCF AJAX-enabled service or through ADO.NET data services. In read-write scenarios, you typically use a DataContext class to track changes to data items in the client, and to provide support for saving changes back to the service. If you are using an ADO.NET data service, you should use the AdoNetDataContext class instead of the more general-purpose DataContext class. (The AdoNetDataContext class derives from the DataContext class.) For reading and writing scenarios, the AdoNetDataContext class uses the AdoNetServiceProxy class internally to call the ADO.NET data service.

The AdoNetDataContext class provides additional support for features that are specific to ADO.NET, such as identity management, links and associations between entity sets that are returned in different fetch operations, hierarchical data, and optimistic concurrency.

The following example shows how to use code to instantiate a AdoNetDataContext class and use it as data provider for a DataView object.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Sys.Data.AdoNetDataContext</title>
  <link href="../styles/divList.css" rel="stylesheet" type="text/css" />
  <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjax.js"></script>
  <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjaxTemplates.js"></script>
  <script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjaxAdoNet.js"></script>
  <script type="text/javascript">
    var imagesDataContext = $create(Sys.Data.AdoNetDataContext, { serviceUri: '../Services/ImagesDataService.svc' });
  </script>
</head>

<body xmlns:sys="javascript:Sys"
    xmlns:dataview="javascript:Sys.UI.DataView"
    sys:activate="*">

  <ul class="list sys-template"
      sys:attach="dataview"
      dataview:autofetch="true"
      dataview:dataprovider="{{ imagesDataContext }}"
      dataview:fetchoperation="Images"
      dataview:fetchparameters="{{ {$orderby: 'Name'} }}"
  >
    <li>
      <span class="name">{{ Name }}</span>
      <span class="value">{{ Description }}</span>
    </li>
  </ul>
</body>
</html>

For more information about the AdoNetDataContext class, see How to: Instantiate an AJAX DataView Control Declaratively.

Data Classes for Templates

The following table lists the data classes in ASP.NET AJAX. that are related to templates.

Name

Description

Sys.UI.DataView Class

Uses a template to display a view of a data from a data source, such as a Web service.

Sys.UI.DataViewItemEventArgs Class

Represents an item (row) that is displayed by a DataView object.

Sys.UI.Template Class

Represents markup that can be instantiated multiple times.

Sys.UI.TemplateContext Class

Represents the results of instantiating a template.

Sys.Data.ChangeOperation Class

Describes a single change in a set of data.

Sys.Data.ChangeOperationType Enumeration

Describes how a data item has changed.

Sys.Data.DataContext Class

Provides members for managing data from a data source and for submitting changes to the data provider.

Sys.Data.DataEventArgs Class

Provides data events that can be canceled.

Sys.Data.MergeOption Enumeration

Describes how an item has changed.

Sys.Data.IDataProvider Interface

Provides an interface for retrieving data from a data provider.

See Also

Tasks

Other Resources

ASP.NET AJAX and Data Management