题记:本想译完这篇来自 Bipin Joshi 的文章,但发现第二篇关于AJAX的文章有些过于简单,于是我想把MSDN上的一篇最新的关于AJAX的文章译过来,以供大家参考!由于这篇文章有很多地方,在上篇文章中已经阐述,所以就按自己的想法,译下了这篇文章。
在这篇文章当中,在使用AJAX时,有了不同的方式,而这种方式更宜于。NET时代的编程人员的理解和运用。本文中提到了AJAX。NET的概念,这是对AJAX的升级应用,简化了使用程序,使用编程效率大大提高。
AJAX.ET
AJAX.NET文档,网站的开发者做了一个很不错的工作,它可以让我们很容易应用和开发自己的WEB程序。在谈到具体的例子之前,我们先要简要介绍一下关于这项技术的一些核心知识。
首先,从AJAX.NET project Web site下载AJAX文件,然后,在你的IIS中建立一个工程(VB。NET或是C#都可以),再添加AJAX。DLL文件的引用。接下来要做的只是简单的配置一下你的WEB。CONFIG文件中的《SYSTEM。WEB》节点。
<
configuration
>
<
system.web
>
<
httpHandlers
>
<
add verb
=
"
POST,GET
"
path
=
"
ajax/*.ashx
"
type
=
"
Ajax.PageHandlerFactory, Ajax
"
/>
httpHandlers
>
![dot.gif](/Images/dot.gif)
system.web
>
configuration
>
为了让服务器端方法可以通过JS来调用,我们需要做二件事情。第一,这个方法必须用
Ajax.AjaxMethodAttribute来声明。第二,在页面的LOAD事件中,我们必须使这个方法注册为通过Ajax.Utility.RegisterTypeForAjax来调用。不用担心,听起来挺复杂的,但是在你的代码当中只要加入几行额外的代码,让我们看实现代码:
//C#
public
class
Sample : System.Web.UI.Page
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
private void Page_Load(object sender, System.EventArgs e)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//Register the class containing the server-side function
//we are interested in
Ajax.Utility.RegisterTypeForAjax(typeof(Sample));
}
[Ajax.AjaxMethod()]
public string GetMessageOfTheDay()
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return "Experience is the mother of wisdom";
}
}
VB.NET
Public
Class Sample
Class Sample
Inherits System.Web.UI.Page
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub Page_Load()Sub Page_Load(sender AsObject, e As EventArgs)
Handles MyBase.Load
'Register the class containing the server-side function
'we are interested in
Ajax.Utility.RegisterTypeForAjax(GetType(Sample))
End Sub
<Ajax.AjaxMethod()> _
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Function GetMessageOfTheDay()Function GetMessageOfTheDay() As String
Return "Experience is the mother of wisdom"
End Function
End Class
在下面的例子当中,我们先讲一个AJAX。NET的一个SAMPLE类的友元方法。这个过程发生在相同类的相同页面中,但是,它可以是任何。NET类,或是任何在。NET类中用AjaxMethodAttribute进行申明的类,这就有一个简单的类方法:GetMessageOfTheDay。
接下来,我们只要做的是,在JS中应用这些方法。AJAX。NET自动生成一个被注册的SAMPLE类,该类中有一个名字和AJAXMETHOD方法一样的(在此是GetMessageOfTheDay)如下所示:
<
script language
=
"
javascript
"
>
Sample.GetMessageOfTheDay(GetMessageOfTheDay_CallBack);
function
GetMessageOfTheDay_CallBack(response)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
alert(response.value);
}
script
>
在JS中的
GetMessageOfTheDay方法需要与服务器端方法相同的参数(在这没有参数),此外,JS中的callback
方法,执行并传递response,直到结束。在这,我们可以看到异步的AJAX工作的实质,因为
GetMessageOfTheDay
方法的调用并没妨碍JS中其它的操作,也没有妨碍页面中用户的继续操作。当服务器端执行完毕,
AJAX。NET调
用
GetMessageOfTheDay_CallBack方法,并传递来自服务器端的结果集。服务器和JS,看起来有些模糊,难以
理解,下面的图例可以帮你很好的了解这一复杂的过程。
还有很多AJAX。NET的有趣之处,比如,它扶持很多。NET的类型,还可以返回很多种不同的值类型,如:XML,DATASET
等。在下面的实际例子当中,你才能体会它如果帮你创建更智能的WEB应用程序。
[注:原文中,下面的例子是一个关于DROPDOWNLIST的级联显示的,在前面提到过,在这就不做描述,相关代码
请参见原文,下面仔细讲解关于文档操作的例子,很有挑战性,千万别走开,会有更精彩的]
例子2:文档锁
这个例子中我们将介绍一个文档管理系统,当然如其它的系统一样,我们提供concurrency management(我译作
:同步在线编辑管理)。也就是说,我们需要一个解决方法,来处理不同的用户来编辑相同的文档。就此,我们会
产生一个”锁装置“类型,来控制多人操作同一文件的可能。利用AJAX我们会让用户有更愉快的文档管理体验。
首先,我们产生一个用户已经在进行编辑的文档队列,并自动提示用户不能修改。第二,我们要确定当用户离开
当前编辑室模式时,文档不会被一直锁住。为此,在这个指导文档中,我们将跳过与AJAX的执行无关的方描述。
然而在下载文档中,会有详细的说明。
首先,当用户试图编辑一个文档时,我们会从此文档得到一个排外锁,如果没有,则把文档加到用户的编辑文档队列中,
并返回首页。这没有什么特别的,只是在我们的代码中添加一些必要的行,下面就是在ONLOAD事件中的例子:
if
(
!
Page.IsPostBack)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
//should validate user input
Document document = GetDocument(Request.QueryString["id"]);
//We have the document, but can't edit it!
if (!Locker.AcquireLock(document))
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//let's add it to the user's list of docs to watch
User.CurrentUser.AddDocumentToQueue(document.DocumentId);
Response.Redirect("DocumentList.aspx");
}
//ok, we have the document and CAN edit it
//![dot.gif](/Images/dot.gif)
}
最关键的行是把文档添加到当前用户的队列中,其实是添加到SESSION中去。下面,产生一个用户控件,可以放在
任何页面上,可以通知用户任何可以编辑的文档。这个用户控件仅包含一个AJAX方法,下面是具体的代码:
Private
Sub Page_Load()
Sub Page_Load(s As Object, e As EventArgs)
Handles MyBase.Load
Ajax.Utility.RegisterTypeForAjax(GetType(UnlockNotifier))
End Sub
![None.gif](/Images/OutliningIndicators/None.gif)
'
Loops through the queued documents and checks if they're available
<
Ajax.AjaxMethod()
>
_
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public
Function GetUnlockedDocuments()
Function GetUnlockedDocuments() As DocumentCollection
'Get all the queued document ids belonging to the user
Dim queuedDocument As ArrayList = User.CurrentUser.DocumentQueue
Dim unlocked As DocumentCollection = New DocumentCollection
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
For Each documentId As Integer In queuedDocumentIds
'If the queued document is no longer locked
If Not Locker.IsLocked(documentId) Then
unlocked.Add(Document.GetDocumentById(documentId))
End If
Next
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
Return unlockedDocuments
End Function
现在我们要做的是在JS中实现请求和处理返回结果,我们会放置一个文档释放信息,如果有,将依据返回结果建
一个动态表格。详细的HTML代码如下:
<
div
id
="notifyBox"
style
="display:none;"
>
<
b
>
The following queued documents can now be edited
b
>
<
table
cellpadding
="5"
cellspacing
="0"
border
="0"
style
="border:1px solid #EEE;"
id
="notifyTable"
>
table
>
div
>
如果没有文档显示的话,我们用一个DIV标签来隐藏该区域(或是该用户列中没有文档),表格用来显示结果
我们将用一个轮流检测系统来查看是否有可用文档,一般来说,这意味着我们要一直调用服务器端方法,用一个
延迟,来显示结果。第一个方法只是在页面加载时才触发,后来的方法会X秒调用一次。
<
script language
=
"
javascript
"
>
window.setTimeout(
"
PollQueue();
"
,
2000
);
//
fires every 2 seconds to check if a queued document was released
//
in a real system with a lot of users, 2 seconds might put too high
//
a load on the server. We could even check first to see if the user
//
even has anything queued, but we'll certainly need to do some
//
performance testing
function
PollQueue()
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
//UnlockNotifier is the type we registered with Ajax.NET
//GetUnlockedDocuments is a method within that type marked with
//the AjaxMethod attribute
UnlockNotifier.GetUnlockedDocuments(PollQueue_CallBack);
//calls itself every 2 seconds
window.setTimeout("PollQueue();", 2000);
}
script
>
余下我们要做的就是处理返回的结果值。首先,检测是否有什么错误没,得到结果值,循环显示文档,自动
生成HTML,这样的话,需要加入下面的行到我们的表格中。
function
PollQueue_CallBack(response)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
var notifyBox = document.getElementById("notifyBox");
var notifyTable = document.getElementById("notifyTable");
//if we couldn't find our table notification box
if (notifyBox == null || notifyTable == null)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
//if the server-side code threw an exception
if (response.error != null)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
notifyBox.style.display = "none";
alert(response.error); //we should probably do better than this
return;
}
var documents = response.value;
//if the response wasn't what we expected
if (documents == null || typeof(documents) != "object")
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
notifyBox.style.display = "none";
return;
}
for (var i = 0; i < notifyTable.rows.length; ++i)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
notifyTable.deleteRow(i);
}
for(var i = 0; i < documents.length; ++i)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
var row = notifyTable.insertRow(0);
row.className = "Row" + i%2;
var cell = row.insertCell(0);
cell.innerHTML = documents[i].Title;
cell = row.insertCell(1);
var date = documents[i].Created;
cell.innerHTML = date.getDay() + "/" + date.getMonth()
+ "/" + date.getYear();
cell = row.insertCell(2);
cell.innerHTML = ""
+ documents[i].DocumentId + "'>edit";
}
notifyBox.style.display = "block";
}
在这个系统中,最新颖的特色是,当用户离开或关闭,或是返回页面时,文档会自动解锁。这个功能的实现,是依靠,JS中的两个方法:
OnBeforeUnLoad 或是
OnUnload ,打开一个新的弹出窗口,在加载时做一些清理工作,然后自行关闭。然而,如果你的浏览器不支持或阻止了这一窗口,那么就没法处理这些工作,导致文件被永久性锁住。为了解决这个问题,我们通过调用服务器端方法解决它。在编辑页面,加一个锁,添加一些JS代码就OK了。
<
script language
=
"
javascript
"
>
//
Makes sure the document is unlocked if the user closes the
//
browser or hits the back button
window.onbeforeunload
=
ReleaseLock;
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
function
ReleaseLock()
{
Locker.ReleaseDocument(DocumentID%>);
}
script>
DOCUMENTID 是在页面类文件中定义的,可以存在SESSION中,再通过服务器端方法
ReleaseDocument.
ReleaseDocument 来进行文档解锁。
[译到这,这个例子,就告一段落了,在接下来文章中我将对者的第三个更复杂的例子,就是关于论坛对像搜索的,会是更详细的译述,也随时欢迎来信,共同探讨最新科技]
备注:签于个人水平,文章中难免有错误纰漏这处,敬请原谅!本文章转译自MSDN 不能用于商业用途,如果转载请注明出处