asp.net|数据|显示  在目前的大部分Web程序中,我们都需要显示给用户一些列表数据。ASP.NET中的GridView服务器控件提供了这种功能,Atlas中的客户端控件ListView也可以在客户端提供类似功能,并以AJAX方式运行。虽然您可以使用传统的GridView控件加上Atlas的UpdatePanel提供同样的AJAX运行方式,但是这种实现方式较低效,也不是“纯粹”的Atlas方法。推荐的方法是采用Atlas的客户端控件ListView来代替。不要担心,Atlas的ListView控件和GridView一样简单,而其二者在很多概念方面是相似的,例如ItemTemplate。但是需要注意的是目前IDE中并没有提供对Atlas脚本的智能感知功能,加之Atlas脚本也没有编译时期检查,所以在书写代码的时候应该格外小心。
  使用ListView的时候应该提供给其一些必要的模版(Template),以告诉Atlas应该如何渲染您的内容。ListView中有如下模版:
- layoutTemplate:这个模版用来渲染包含列表项目的容器(例如使用 <table>标记),列表的头部(例如使用 <thead>标记),尾部等。您必须为ListView指定一个layoutTemplate。而且这个模版必须包含一个itemTemplate模版,也可选包含一个separatorTemplate模版。
- itemTemplate:这个模版用来渲染列表中的一个项目(例如使用 <tr>标记)。这个模版必须被置于layoutTemplate中。
- separatorTemplate:这个模版用来渲染列表中的项目之间的分隔元素(例如使用 <hr>标记)。这个模版必须被置于layoutTemplate中。
- emptyTemplate.:这个模版用来渲染没有项目存在时的ListView。此时可能与该ListView相关的DataSource对象中没有项目,或是正在从服务器中取得的过程中。
- itemCssClass:指定项目条目的css class。
- alternatingItemCssClass:指定间隔的项目条目的css class。
- selectedItemCssClass:指定被选中的项目条目的css class。
- separatorCssClass:指定分隔元素的css class。
- itemTemplateParentElementId:这个属性指定了itemTemplate和separatorTemplate的父元素。这样itemTemplate和separatorTemplate元素就可以在其中被重复渲染。
首先,我们编写一个返回.NET中DataTable的Web Service。注意到在这里将继承于Microsoft.Web.Services.DataService基类,并且为service方法加上定义在名称空间System.ComponentModel中的属性DataObjectMethod。在service方法的开头,我们使用System.Threading.Thread.Sleep(2000)来模拟2秒钟的网络延迟,以便可以看到emptyTemplate中的内容。
[WebService(Namespace = "http://tempuri.org/")]
 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
 public class MyService : Microsoft.Web.Services.DataService
public class MyService : Microsoft.Web.Services.DataService  {
{
 [DataObjectMethod(DataObjectMethodType.Select)]
 [DataObjectMethod(DataObjectMethodType.Select)] public DataTable GetListData()
 public DataTable GetListData()
 
  {
{ System.Threading.Thread.Sleep(2000);
 System.Threading.Thread.Sleep(2000); 
  DataTable dt = new DataTable("MyListData");
 DataTable dt = new DataTable("MyListData"); dt.Columns.Add("Name", typeof(string));
 dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Email", typeof(string));
 dt.Columns.Add("Email", typeof(string)); DataRow newRow;
 DataRow newRow; for (int i = 0; i < 5; ++i)
 for (int i = 0; i < 5; ++i)
 
  {
{ newRow = dt.NewRow();
 newRow = dt.NewRow(); newRow["Name"] = string.Format("Dflying {0}", i);
 newRow["Name"] = string.Format("Dflying {0}", i); newRow["Email"] = string.Format("Dflying{0}dflying.net", i);
 newRow["Email"] = string.Format("Dflying{0}dflying.net", i); dt.Rows.Add(newRow);
 dt.Rows.Add(newRow); }
 } return dt;
 return dt; }
 } }
}然后,添加一些ASP.NET页面中必须的控件/标记:
<atlas:ScriptManager ID="ScriptManager1" runat="server" />
 <!-- Element for myList (container) -->
 <!-- Element for myList (container) --> <div id="myList"> </div>
 <div id="myList"> </div> <!-- Layout Elements -->
 <!-- Layout Elements --> <div  none;">
 <div  none;"> </div>
 </div>  在上面的标记中,我们加入了三个标记:一个必须的ScriptManager控件。一个id为myList的div,用来让Atlas把渲染后的ListView放置于这里。一个隐藏的div,用于定义我们的模版。这个隐藏div中的元素在页面上是不可见的,只是用来提供给Atlas必要的模版。
  我们在这个隐藏的div中加入如下ListView的模版:
<!-- Layout Template --> <table id="myList_layoutTemplate" border="1" cellpadding="3">
 <table id="myList_layoutTemplate" border="1" cellpadding="3"> <thead>
 <thead> <tr>
 <tr> <td> <span>No. </span> </td>
 <td> <span>No. </span> </td> <td> <span>Name </span> </td>
 <td> <span>Name </span> </td> <td> <span>Email </span> </td>
 <td> <span>Email </span> </td> </tr>
 </tr> </thead>
 </thead> <!-- Repeat Template -->
 <!-- Repeat Template --> <tbody id="myList_itemTemplateParent">
 <tbody id="myList_itemTemplateParent"> <!-- Repeat Item Template -->
 <!-- Repeat Item Template --> <tr id="myList_itemTemplate">
 <tr id="myList_itemTemplate"> <td> <span id="lblIndex" /> </td>
 <td> <span id="lblIndex" /> </td> <td> <span id="lblName" /> </td>
 <td> <span id="lblName" /> </td> <td> <span id="lblEmail" /> </td>
 <td> <span id="lblEmail" /> </td> </tr>
 </tr> <!-- Separator Item Template -->
 <!-- Separator Item Template --> <tr id="myList_separatorTemplate">
 <tr id="myList_separatorTemplate"> <td colspan="3">Separator </td>
 <td colspan="3">Separator </td> </tr>
 </tr> </tbody>
 </tbody> </table>
 </table> <!-- Empty Template -->
 <!-- Empty Template --> <div id="myList_emptyTemplate">
 <div id="myList_emptyTemplate"> No Data
 No Data </div>
 </div>
  上面的代码中您可以看到我提到的所有四种模版。另外还要指定每一个模版一个id,将用于下面的Atlas脚本声明中。在这个例子中我将以HTML Table的形式渲染这个ListView,很抱歉分隔元素将会很丑陋(一个空行)。
  最后在页面中添加Atlas脚本声明:
<dataSource id="listDataSource" autoLoad="true" serviceURL="MyService.asmx" />
 <listView id="myList" itemTemplateParentElementId="myList_itemTemplateParent">
 <listView id="myList" itemTemplateParentElementId="myList_itemTemplateParent"> <bindings>
 <bindings> <binding dataContext="listDataSource" dataPath="data" property="data" />
 <binding dataContext="listDataSource" dataPath="data" property="data" /> </bindings>
 </bindings> <layoutTemplate>
 <layoutTemplate> <template layoutElement="myList_layoutTemplate" />
 <template layoutElement="myList_layoutTemplate" /> </layoutTemplate>
 </layoutTemplate> <itemTemplate>
 <itemTemplate> <template layoutElement="myList_itemTemplate">
 <template layoutElement="myList_itemTemplate"> <label id="lblIndex">
 <label id="lblIndex"> <bindings>
 <bindings> <binding dataPath="$index" transform="Add" property="text"/>
 <binding dataPath="$index" transform="Add" property="text"/> </bindings>
 </bindings> </label>
 </label> <label id="lblName">
 <label id="lblName"> <bindings>
 <bindings> <binding dataPath="Name" property="text" />
 <binding dataPath="Name" property="text" />  </bindings>
 </bindings> </label>
 </label> <label id="lblEmail">
 <label id="lblEmail"> <bindings>
 <bindings> <binding dataPath="Email" property="text" />
 <binding dataPath="Email" property="text" /> </bindings>
 </bindings> </label>
 </label>  </template>
 </template> </itemTemplate>
 </itemTemplate> <separatorTemplate>
 <separatorTemplate> <template layoutElement="myList_separatorTemplate" />
 <template layoutElement="myList_separatorTemplate" /> </separatorTemplate>
 </separatorTemplate> <emptyTemplate>
 <emptyTemplate> <template layoutElement="myList_emptyTemplate"/>
 <template layoutElement="myList_emptyTemplate"/> </emptyTemplate>
 </emptyTemplate> </listView>
 </listView>
  这里我添加了一个Atlas客户端DataSource对象以从Web Service中取得数据。这里我们暂且不多谈DataSource(可能在后续文章中有所介绍)。让我们来看一下ListView相关的定义:在ListView的定义中,我们指定了itemTemplateParentElementId属性。然后在ListView的内部定义了一个binding段,用来把DataSource中取得的数据与这个ListView绑定起来。我们还定义了四个模版段,每个模版段都用layoutElement与上面定义过的四种模版关联。注意到在layoutTemplate模版中的第一个label控件,我们在其绑定中指定了一个Add transformer以将从0开始的顺序变为从1开始(关于Atlas Transformer,请参考我的这篇文章:)。
  大功告成,运行一下吧。
  装载中:
装载完成:
 
  
 
 
  
