深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一(

本文涉及的产品
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
数据可视化DataV,5个大屏 1个月
简介:
一、引言
最近,微软ASP.NET Ajax 1.0框架正在引起越来越多的web开发者的注意。原因何在?一方面,因为它是微软推荐的一个基于Ajax的主要针对ASP.NET 2.0平台的web开发方案。另一方面,因为这个框架登上Ajax舞台的时间如此之晚,但却把一套新的完整的基于Ajax的web开发方案呈现在web技 术人员的前面—与遗留ASP.NET系统的有机整合并实现了完全面向对象的客户端JavaScript组件模型等!在本系列文章中,我想结合自己近来的学 习详细剖析微软ASP.NET Ajax 1.0框架的客户端数据绑定架构部分所涉及的关键技术。在本篇(上篇)中,我们将主要从理论角度来探讨这个框架的数据绑定架构并给出一个简单示例实现;在 下篇中,我们将通过构建两个具有较大区别的示例(一个例子的数据源直接来源于普通的web服务,而另一个例子的数据源则来自于一个SQL Server 2005数据库)来探讨实际开发环境下的基于ASP.NET Ajax 1.0客户端数据绑定技术的应用程序。
关于ASP.NET AJAX Futures January CTP
首先,让我们来观察一下ASP.NET AJAX框架的整体架构图(图1):
图1:ASP.NET AJAX架构图
通常情况下,我们提到ASP.NET AJAX(以后简称“MS AJAX”)框架时,往往指如下的三个部分:
◆ASP.NET 2.0 AJAX Extensions 1.0。这一部分对应于程序集System.Web.Extensions.dll和 System.Web.Extensions.Design.dll,它们共包含三个JavaScript文件—MicrosoftAjax.js, MicrosoftAjaxTimer.js和MicrosoftAjaxWebForms.js;
◆ASP.NET AJAX Control Toolkit(在前面的图1没有指出),这个包中提供了大量现成的例子并包含一个功能相当强大的SDK,其目的是进一步简化创建定制的ASP.NET AJAX控件及扩展器;
◆ASP.NET AJAX Futures January CTP(最近又刚发行了一个五月版,但本文中的所有概念及例子照样通用),这一部分对应于程序集Microsoft.Web.Preview.dll(包 含三个文件—PreviewScript.js,PreviewGlitz.js和PreviewDragDrop.js)。
【作者注】为了全面理解本文中内容,读者需要安装ASP.NET 2.0 AJAX Extensions 1.0和ASP.NET 2.0 AJAX Futures January CTP(而ASP.NET AJAX Control Toolkit部分可不安装,但强烈建议安装试用)。篇幅所限,对于这些内容的安装不再赘述。
既然在本文中我们的主要目标在于ASP.NET AJAX Futures January CTP(只有它才支持丰富的客户端数据绑定机制),那么现在就让我们开始这一较长的探索历程。
二、命名空间Sys.Preview.Data中的客户端控件简介
从前面的图1中,读者可能会注意到其中有一个基础类库(对应文件PreviewScript.js),这正是整个ASP.NET AJAX Futures January CTP的核心部分。这个库中包含的命名空间和类如下图2所示。
图2:基础类库中的组件
从上图中易见,所有的绑定于数据库及那些负责从web服务中获取数据集的所有的客户端控件都定义于命名空间Sys.Preview.Data中。现在,让我们对其中几个最为重要的控件作一介绍。
(一)DataSource控件
在绝大多数的web应用程序,我们都必须进行数据管理—例如检索和向用户显示数据以及把对对它们的修改保存回数据库等。为此,ASP.NET提供了 一个内置的支持对象—DataSource。MS AJAX客户端脚本库也提供了类似的DataSource概念的支持。图3展示了MS AJAX中的高级数据绑定控件与它们可能的ADO.NET 2.0对应物的比较。
图3:MS AJAX客户端数据源控件与其ADO.NET 2.0对应物间的比较
【作者注】根据我的分析,在最新的AJAX Futures CTP中,DataSet似乎被显式地删除掉了(我仔细分析了所有的相关*.js文件,但是发现在PreviewScript.js文件仅支持DataSetConverter)。
总的来看,在AJAX Futures CTP中共存在两种类型的DataSource:
①Sys.Data.DataSource—用于描述一个表格式数据结构(例如一个数据库查询的结果),非常类似于ASP.NET 2.0中的SQLDataSource对象。这个控件可以用作ListView和ItemView控件的客户端数据源。你完全可以从服务器端加载数据并且 把修改结果保存回服务器端。
②Sys.Data.XMLDataSource—用于描述一个层次式数据结构(例如一个XML文件),非常类似于ASP.NET 2.0中的XMLDataSource对象。这个控件可以用作XSLTView控件的客户端数据源。注意,这是一个只读数据源—你仅可以读取并把数据显示 给用户但是却无法把对它们的修改保存回服务器端。
但请注意在本系列文章中,我们仅探讨前者。
既然所有的客户端高级数据绑定控件都包括于文件PreviewScript.js内,所以让我以图形方式来给出这些控件间的直接关系描述(图4)。
图4:MS AJAX主要数据绑定控件间的层次关系图
下面的列表1相应于DataSource控件的prototype和descriptor定义:
列表1

     
     
Sys.Preview.Data.DataSource.prototype = {
_data: null,
_initialData: null,
_autoLoad: false,
_serviceURL: "",
_loadMethod: "",
_serviceType: Sys.Preview.Data.ServiceType.DataService,
_isReady: true,
_dataChangedDelegate: null,
_request: null,
_timeout: 0,
//……omitted
_onDataAvailable: Sys$Preview$Data$DataSource$_onDataAvailable,
get_data: Sys$Preview$Data$DataSource$get_data,
set_data: Sys$Preview$Data$DataSource$set_data,
get_initialData: Sys$Preview$Data$DataSource$get_initialData,
set_initialData: Sys$Preview$Data$DataSource$set_initialData,
get_isDirtyAndReady: Sys$Preview$Data$DataSource$get_isDirtyAndReady,
get_isReady: Sys$Preview$Data$DataSource$get_isReady,
_set_isReady: Sys$Preview$Data$DataSource$_set_isReady,
get_loadMethod: Sys$Preview$Data$DataSource$get_loadMethod,
set_loadMethod: Sys$Preview$Data$DataSource$set_loadMethod,
get_parameters: Sys$Preview$Data$DataSource$get_parameters,
get_serviceURL: Sys$Preview$Data$DataSource$get_serviceURL,
set_serviceURL: Sys$Preview$Data$DataSource$set_serviceURL,
get_serviceType: Sys$Preview$Data$DataSource$get_serviceType,
set_serviceType: Sys$Preview$Data$DataSource$set_serviceType,
get_rowCount: Sys$Preview$Data$DataSource$get_rowCount,
initialize: Sys$Preview$Data$DataSource$initialize,
onDataPropertyChanged: Sys$Preview$Data$DataSource$onDataPropertyChanged,
onRequestComplete: Sys$Preview$Data$DataSource$onRequestComplete,
onLoadComplete: Sys$Preview$Data$DataSource$onLoadComplete,
ready: Sys$Preview$Data$DataSource$ready,
load: Sys$Preview$Data$DataSource$load,
save: Sys$Preview$Data$DataSource$save
}
Sys.Preview.Data.DataSource.descriptor = {
properties: [ { name: 'data', type: Object },
{ name: 'autoLoad', type: Boolean },
{ name: 'initialData', type: String },
{ name: 'isDirtyAndReady', type: Boolean, readOnly: true },
{ name: 'isReady', type: Boolean, readOnly: true },
{ name: 'loadMethod', type: String },
{ name: 'rowCount', type: Number, readOnly: true },
{ name: 'serviceURL', type: String },
{ name: 'parameters', type: Object, readOnly: true },
{ name: 'serviceType', type: Sys.Preview.Data.ServiceType } ],
methods: [ { name: 'load' },
{ name: 'save' } ],
events: [ { name: 'dataAvailable', readOnly: true } ]
}
Sys.Preview.Data.DataSource.registerClass('Sys.Preview.Data.DataSource', Sys.Component);
【注】这段代码截获于调试过程中的源码文件。
根据我的分析,上面所有prototype块中的内容均可以用于JavaScript编程中,但是仅有那些位于descriptor块中的内容才可用于xml-script声明性编程中(在本系列中,我们将主要讨论这种方法)。
DataSource控件中唯一的事件—dataAvailable
DataSource控件仅含有一个自定义的(不包含那些继承自父类的事件)也是非常重要的事件—dataAvailable。当 DataSource控件中的数据加载完成时激活这个事件。从随同MS AJAX的示例Tasklist中,我们可以看到这个事件的典型应用,如下:
列表2—控件DataSource的事件dataAvailable的典型应用场所

     
     
<components>
<dataSource id="listsDataSource" serviceURL="TaskListDataService.asmx" />
<dataSource id="itemsDataSource" serviceURL="TaskItemDataService.asmx">
<dataAvailable>
<invokeMethodAction target="listsDataSource" method="load" />
</dataAvailable>
</dataSource>
在此,以声明方式定义了两个DataSource控件。当第二个DataSource itemsDataSource完成加载后,然后调用第一个DataSource的load方法。
下表列出了相应于DataSource控件中的自定义方法。
方法名
描述
load
从服务器端检索数据(根据当前 DataSource 的配置对服务器端进行查询)。
Save
根据当前 DataSource 的配置,显式地把数据写向或更新到服务器端—也即是把客户端所作改变保存回服务器。
下面是控件DataSource的方法Save在文件PreviewScript.js中的定义:
列表 3

     
     
function Sys$Preview$Data$DataSource$save() {
//……省略
if (this._serviceType === Sys.Preview.Data.ServiceType.DataService) {
var method = "SaveData";
var params = {changeList: changes, parameters: this._parameters,
loadMethod: this._loadMethod};
var onComplete = Function.createDelegate(this, this.onLoadComplete);
var onError = Function.createDelegate(this, this.ready);                
this._request = Sys.Net.WebServiceProxy.invoke(this._serviceURL,
method, false, params, onComplete, onError, this, this._timeout);
}
else {
throw Error.createError("Save is not supported in Handler mode.");
}
从上面的代码中明显看出,只有当属性serviceType的类型被设置为类型DataService时才可以使用Save方法。当我们定义将用于在客户端消费的web服务时这是相当重要的。关于其中的“神秘”方法—SaveData,我们将留于下篇中再讨论。
有关控件DataSource中的自定义属性,请参考如下表格。
属性名
描述
autoLoad
Boolean 值,用于指明是否这个数据源控件在初始化后将自动地从服务器端加载数据。注意,如果你想在页面加载时就应该指定数据源的内容,则应使用 initialData 属性;否则的话,在页面加载后,还需要一次到服务器端的信息馈送。
initialData
伴随页面的加载提供的初始数据。有些场所下,当用户第一次进入页面时就应该在页面中显示一些初始的数据—例如某个列表的第一页的记录。
isDirtyAndReady
指示是否当前 DataSource 已经完成数据加载,并且数据非空,且数据没有发生改变。
loadMethod
另一个有些“神秘”的方法(我们将在下篇的关于 DataService 处讨论它)。
rowCount
返回 data 属性中实际数据的行数。
serviceURL
Web 服务的 URL DataSource 可以从中检索数据。注意,你应该总是设置这个属性。
parameters
添加到服务 URL 后的参数。仅用于当 serviceType 的类型设置为 handler 时。
serviceType
用于指定 web 服务的类型,可以被设置为 DataService handler 。缺省情况下(也是推荐的)值为 DataService ,这意味着你的服务要派生自 Microsoft.Web.Services.DataService 并且应该为典型的数据库 CRUD 操作提供内置的支持。
Id (定义于父类中)
控件标识。
data
检索自服务器端数据库中的数据,存储于客户端。注意:这个属性仅可以为Array类型或Sys.Preview.Data.DataTable类型。
isReady
指示是否这个DataSource已经完成从服务器加载数据。你可以把这个属性绑定到一个数据绑定控件的enabled属性上,以便当数据正处于加载过程时禁止使用此绑定控件。
下面,我们来讨论另一个DataSource相关控件—DataView。
(二)DataView控件
一般说来,我们可以从服务器端获取数据并且通过使用DataSource把它们存储于客户端,然后使用DataTable对象修改我们在客户端取得 的数据。然而,有时我们需要在实际展示数据前作一些“修饰”—例如,当数据包含成千上万行记录时我们可以对页面加以分页显示,或者我们的用户仅对其中的一 少部分数据感兴趣。为此,MS AJAX框架又引入了DataView和DataFilter两个对象。
DataView控件中定义的属性列表。
属性名
描述
data
被修饰的实际数据,类型为 Sys.Data.IData Sys.IArray
filteredData
过滤数据,例如分页数据或经排序的数据。
filters
一个 DataFilter 对象的集合,用于过滤数据。你可以为 DataView 指定一组过滤器并把它们逐个应用于你的数据。
hasNextPage
是否存在下一个页面。
hasPreviousPage
是否存在上一个页面。
length
在当前页面中有多少行。
pageCount
在当前 DataView 中有多少页。
pageIndex
当前页面索引。
pageSize
每一页中有多少行。如果你需要对你的数据进行分页,则应该设置这个属性。
sortColumn
排序记录行所依据的列。如果你需要排序,则应该设置这个属性。
sortDirection
排序的方向,或者是 Ascending (缺省的值)或者是 Descending
注意,这个DataView对象仅有一个自定义方法—sort。这个方法将根据sortColumn属性和sortDirection属性对数据进 行排序操作。此外,你还可以使用命名空间Sys.Preview.UI.Data中的另外两个控件—DataNavigator和 SortBehavior来帮助你实现分页和排序。在此,为了完整起见,我们还想对DataFilter对象作一简介。
类Sys.Preview.Data.DataFilter被设计为所有过滤器的抽象基类。它提供一个抽象方法filter以便在派生类中实现特定的过滤规则。
此外,在Futures January CTP中还提供了一个内置的过滤器—PropertyFilter,通过一个指定的属性及其属性值来过滤数据项。
【作者注】首先,这个DataView控件与ADO.NET 2.0提供的DataView控件存在相当不同。其次,因为我们的示例中主要使用的是ListView和ItemView控件,所以对此有兴趣的读者可以从 这里得到一个相关示例(尽管这个例子是以前版本的Atlas提供的,但是参考本文中的相关示例,你可以略加修改即可在新环境下运行)。
(三)DataTable控件
现在,我们来讨论另一个重要的控件—DataTable,这个控件实现了Sys.Data.IData接口。通过分析随同MS AJAX框架发行的源代码及示例程序,我们可以容易地发现许多重要的控件(例如DataSource,DataView,ItemView和 ListView)都使用该DataTable控件来存储它们的数据。因此,当你在MS AJAX中使用数据绑定时,你将经常与这个控件打交道。但篇幅所限,在此,我们也仅列出它的常用事件、属性和方法。
DataTable控件中的事件定义:
事件名
描述
collectionChanged
当行集合改变时(例如添加,删除或者修改)调用。
propertyChanged
无论何时改变一个或多个属性时都被调用。
DataTable控件中的属性定义:
属性名
描述
columns
返回一个 Sys.Preview.Data.DataColumn 数组,类似于一个数据库表格的结构。
keyNames
返回一个字符串数组,用于描述 DataTable 中的关键字列。
length
返回 DataTable 中所有记录的总数。
isDirty
如果 DataTable 中的数据已经改变并且还没有被写回到数据库,那么,这个属性被置为 true ;否则为 false
DataTable控件中的方法定义:
方法名
描述
Delete rowObject
从当前 DataTable 中删除一行(即对应作为参数的行)
get_length ()
返回记录总数
add rowObject
在当前 DataTable 的最后添加一个新行
clear ()
删除当前 DataTable 中的所有数据
createRow initialData
根据当前列结构创建一个新的 Sys.Preview.Data.DataRow
getChanges ()
返回针对当前 DataTable 的修改操作,返回值为下列之一:
·          Updated最近更新Sys.Preview.Data.DataRow
·          inserted新插入的Sys.Preview.Data.DataRow
·          Deleted删除的Sys.Preview.Data.DataRow
getColumn name
根据传递的列名从该 DataTable 中返回一个 DataColumn 对象。
getRow index
返回一个对象 DataRow
getItem index
与方法 getRow相同
(四)DataColumn及DataRow控件
读者应该很容易猜出,前面的DataTable包含一个DataColumn对象的集合和一个DataRow对象的集合。既然客户端 DataColumn和DataRow控件的设计是用于模仿它们的ADO.NET2.0对应物—DataColumn和DataRow,所以,我们可以从 前面的图3中非常容易地理解它们的对应关系。篇幅所限,我们在此省略对这两个控件的讨论。
现在,让我们转而讨论另一个命名空间—Sys.Preview.UI.Data中的几个重要控件。














本文转自朱先忠老师51CTO博客,原文链接: http://blog.51cto.com/zhuxianzhong/59834 ,如需转载请自行联系原作者



相关实践学习
DataV Board用户界面概览
本实验带领用户熟悉DataV Board这款可视化产品的用户界面
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
相关文章
|
6月前
|
开发框架 前端开发 JavaScript
ASP.NET AJAX使用方法概述(三)
ASP.NET AJAX使用方法概述(三)
51 1
|
3月前
|
开发框架 .NET 数据库连接
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
|
4月前
|
开发框架 JSON 前端开发
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
|
3月前
|
Web App开发 数据采集 开发框架
在.NET程序中整合微软的Playwright,使用 Playwright 的最佳实践和技巧
在.NET程序中整合微软的Playwright,使用 Playwright 的最佳实践和技巧
|
6月前
|
开发框架 缓存 前端开发
安装ASP.NET AJAX (一安装)
安装ASP.NET AJAX (一安装)
103 0
|
6月前
|
SQL 开发框架 .NET
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
119 0
|
6月前
|
SQL 开发框架 前端开发
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
85 0
|
11月前
|
人工智能 编解码 Cloud Native
微软发布 .NET 8 开源开发平台:引入 PGO、AVX-512 支持,性能提升 20%
对企业来说特别重要的是,.NET 8 是一个长期支持 (LTS) 版本,这意味着它将获得三年的支持和补丁,而标准期限支持 (STS) 版本则是 18 个月。对于开发人员来说,特别重要的是 .NET 团队正在向期待已久的原生提前编译(NativeAOT)迈进 。
227 2
|
开发框架 前端开发 .NET
用ajax和asp.net实现智能搜索功能
用ajax和asp.net实现智能搜索功能
78 0
|
SQL 开发框架 监控
下一篇
无影云桌面