深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一(-阿里云开发者社区

开发者社区> 技术小甜> 正文

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

简介:
+关注继续查看
一、引言
最近,微软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):
1558260.gif
图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所示。
1558261.gif
图2:基础类库中的组件
从上图中易见,所有的绑定于数据库及那些负责从web服务中获取数据集的所有的客户端控件都定义于命名空间Sys.Preview.Data中。现在,让我们对其中几个最为重要的控件作一介绍。
(一)DataSource控件
在绝大多数的web应用程序,我们都必须进行数据管理—例如检索和向用户显示数据以及把对对它们的修改保存回数据库等。为此,ASP.NET提供了 一个内置的支持对象—DataSource。MS AJAX客户端脚本库也提供了类似的DataSource概念的支持。图3展示了MS AJAX中的高级数据绑定控件与它们可能的ADO.NET 2.0对应物的比较。
1558262.gif
图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)。
1558263.gif
图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服务的URLDataSource可以从中检索数据。注意,你应该总是设置这个属性。

parameters

添加到服务URL后的参数。仅用于当serviceType的类型设置为handler时。

serviceType

用于指定web服务的类型,可以被设置为DataServicehandler。缺省情况下(也是推荐的)值为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.IDataSys.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控件中的方法定义:
方法名

描述

DeleterowObject

从当前DataTable中删除一行(即对应作为参数的行)

get_length()

返回记录总数

addrowObject

在当前DataTable的最后添加一个新行

clear()

删除当前DataTable中的所有数据

createRowinitialData

根据当前列结构创建一个新的Sys.Preview.Data.DataRow

getChanges()

返回针对当前DataTable的修改操作,返回值为下列之一:

·         Updated最近更新Sys.Preview.Data.DataRow

·         inserted新插入的Sys.Preview.Data.DataRow

·         Deleted删除的Sys.Preview.Data.DataRow

getColumnname

根据传递的列名从该DataTable中返回一个DataColumn对象。

getRowindex

返回一个对象DataRow

getItemindex

与方法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,如需转载请自行联系原作者



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
8940 0
【spring 注解 错误】使用controller 作为后台给前台ajax交互数据出错
controller作为后台与前台的ajax进行交互,后台的方法处理完成返回一个boolean类型的值,想传给前台用来判断是否执行成功,BUT,问题来了: 1 严重: Servlet.service() for servlet rest threw exception 2 java.
703 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10685 0
python爬虫AJAX数据爬取和HTTPS访问 | python爬虫实战之四
本节介绍了通过“豆瓣电影”来进行了json数据的处理,另外说明了HTTPS访问需要获得CA证书。使用HTTPS加密数据更加安全。
1397 0
IE浏览器下ajax缓存导致数据不更新的解决方法
摘自:http://www.iefans.net/ie-ajax-json-shuju-huancun/ 最近做设计的时候遇到一个小问题,当你用jquery的getjson函数从后台获取数据的时候,IE浏览器会自动设置缓存,如果此时你对数据进行修改的时候刷新页面,IE并不会在页面显示你修改后的数据,因为你刷新的时候IE浏览器会查找缓存并显示你修改前的数据,最后在网上查了些资料终于解决了IE浏览器下的问题。
1031 0
如何用 ajax 连接mysql数据库,并且获取从中返回的数据。ajax获取从mysql返回的数据。responseXML分别输出不同数据的方法。
开讲前,先说下网上,大部分的关于这方面的博文或者其他什么的,就我自己的感觉,第一说得不详细,第二语言不能很好的被初学者了解。 我这篇博文的标题之所以用了三句,是为了方便其他人好查找;       这里介绍的方法有什么用呢? 使用它,就可以无闪刷新页面,并且从数据库获取实时改变的数据反馈回界面,显示出来!是不是很爽,的确。
990 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
11972 0
Ajax-09:服务端响应JSON数据
Ajax-09:服务端响应JSON数据
12 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
12607 0
+关注
10146
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载