AJAX DataGrid






4.57/5 (21投票s)
2007年6月1日
4分钟阅读

111871

2018
本文演示了如何结合我上一篇文章中的 JavaScript DataGrid 来使用 AJAX 技术。
引言
AJAX(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)不是一项技术,而是一种利用多项技术的技术。
- HTML 和 CSS 用于标记和样式化信息。
- Document Object Model (DOM),通过客户端脚本(主要是 ECMA 脚本实现,如 JavaScript 和 JScript)访问,用于显示和交互呈现的信息。
- XML 通常用作客户端和服务器之间传输数据的格式。但并非强制要求;即使是纯文本也可以用作数据格式。在某些情况下,也可以使用预格式化的 HTML、JSON、纯文本甚至 EBML。
XMLhttpRequest
对象用于与服务器异步交换数据。在某些 AJAX 框架和某些情况下,会使用IFrame
对象与服务器交换数据,而在其他情况下,则会使用动态添加的“script”标签。
如上所述,AJAX 本身并非一项技术。它类似于 DHTML,指的是一系列技术(标记语言(如 HTML)、客户端脚本语言(如 JavaScript)、演示文稿定义语言(Cascading Style Sheets, CSS)和 Document Object Model)。AJAX 的主要元素是 XMLhttpRequest
,它允许浏览器向服务器发出动态异步请求,而无需重新加载页面。XmlHttpRequest
可以消除页面刷新的需求,并且在这种开发方法下,其他技术的使用和突出程度会更高。当使用 XMLHttpRequest
对象时,大量使用 JavaScript、CSS 和 DOM 会变得更加重要,并且它们会结合使用,以提供更高级的“单页”体验。其他技术之所以被包含在此术语中,是因为它们与用户体验相关,当与 XMLHttpRequest
结合使用时。
使用 AJAX 的原因
使用 AJAX 最明显的原因是改善用户体验。使用 AJAX 的页面比典型的网页更像独立的应用程序。单击导致整个页面重新加载的链接看起来是一种繁重操作。通过 AJAX,页面通常可以动态更新,从而更快地响应用户交互。一些人认为它将成为一项重要的技术,并将使 Web 比现在更好。
AJAX 的实现
在当前项目的示例中,我采用了 AJAX 开发方法来动态显示和交互呈现的信息。我决定结合我之前文章中的 JavaScript Grid 和 Web Service。本文展示了如何在客户端简单地将我的 JavaScript Grid 与 AJAX 一起使用。由于客户端和服务器代码已经完成,我需要做的就是将它们整合到一个应用程序中。将 Grid 引入 Web 应用程序非常简单。我需要在客户端创建一个代理类来处理 Web Service。我创建了三个类:ProxyHelper
、CustomerProxy
和 OrderProxy
。ProxyHelper
类是一个实用类,CustomerProxy
和 OrderProxy
类都使用此类向 Web Service 发送 SOAP 请求。
function ProxyHelper()
{
var httpObj = new ActiveXObject("Microsoft.XMLHTTP");
httpObj.onreadystatechange = onReadyStateChange;
var thisRef = this;
this.onDataLoaded;
this.send = function(strRequest , soapAction, servicePath)
{
httpObj.open("POST", servicePath, true);
httpObj.setRequestHeader("SOAPAction",soapAction );
httpObj.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
httpObj.send(strRequest);
}
function onReadyStateChange()
{
if(httpObj.readyState == 4)
{
if(httpObj.status == 200)
{
if(thisRef.onDataLoaded!=null)
{
httpObj.responseXml.setProperty("SelectionLanguage", "XPath");
thisRef.onDataLoaded(httpObj.responseXml);
}
}
else
{
alert("Status: "+httpObj.statusText+".\nResponseText:
"+httpObj.responseText);
}
}
}
}
customerProxy
和 orderProxy
类都有两个事件:onDeserialized
、onXmlDataLoaded
,它们在接收到 Web Service 的数据时触发。这些类还具有相应的 D方法来调用 Web Service 的方法,例如“CreateCustomer
、CreateOrder
、UpdateOrder
、GetCustomers
等”。这些 D方法具有与 Web Service 方法相同的签名。
当 XML 数据加载完成后,会触发 onXmlDataLoaded
事件,而当 XML 数据加载并反序列化为对象后,会触发 onDeserialized
事件。onXmlDataLoaded
的参数是 XMLDocument
,而 onDeserialized
的参数是反序列化后的对象。
function CustomerProxy()
{
var path = "../Server/Customer.asmx";
var proxyHelper = new ProxyHelper();
proxyHelper.onDataLoaded = onDeserialize;
var thisRef = this;
this.onDeserialized;
this.onXmlDataLoaded;
function onDeserialize(responseXml)
{
if(thisRef.onXmlDataLoaded!=null)
thisRef.onXmlDataLoaded(responseXml);
if(thisRef.onDeserialized==null)
return;
thisRef.onDeserialized(deserializeXML(responseXml));
}
this.getCustomers = function()
{
var soapRequest = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
soapRequest += "<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
soapRequest += " xmlns:xsd=\http://www.w3.org/2001/XMLSchema\
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> ";
soapRequest += " <soap:Body><GetCustomers
xmlns=\"http://tempuri.org/\" /></soap:Body></soap:Envelope>";
proxyHelper.send(soapRequest,"http://tempuri.org/GetCustomers",path);
}
...
}
我在客户端编写了一个简单的实用函数 called "deserializeXML
",它将 XML 转换为 JS 对象。
function deserializeXML(responseXml)
{
var result = responseXml.documentElement.selectSingleNode
("./child::*/child::*/child::*");
if(result.firstChild==null)
return emptyResponse;
if(result.firstChild.nodeType==1)
{
var resultArray = new Array();
for(var index = 0; index < result.childNodes.length; index++)
{
//convert the XML node into js object and add item to result array
resultItem = result.childNodes[index];
var customer = new Object();
for(var index1 = 0; index1 < resultItem.childNodes.length;
index1++)
{
customer[resultItem.childNodes[index1].nodeName] =
resultItem.childNodes[index1].text;
}
resultArray.push(customer);
}
return resultArray;
}
else
//return the result value without any serialization
//as return value is supposed to be a primitive data type such as int,
//boolean etc.
return result.firstChild.nodeValue;
}
我在服务器端也采用了类似的方法,特别是在 XMLRepository
数据源上。我需要将传输对象保存到 XML 中。我编写了一个具有两个静态 D方法的实用类。
public class Serialization
{
public static T FillObjectFromXMLDoc<T>(XmlDocument xmlDoc)
{
using (MemoryStream memoryStream = new MemoryStream())
{
StreamWriter streamWriter = new StreamWriter(memoryStream);
streamWriter.Write(xmlDoc.OuterXml);
streamWriter.Flush();
XmlSerializer serilazer = new XmlSerializer(typeof(T));
memoryStream.Position = 0;
T obj = (T)serilazer.Deserialize(memoryStream);
return obj;
}
}
public static XmlDocument FillXmlDocFromObject<T>(T obj)
{
using (MemoryStream memoryStream = new MemoryStream())
{
StreamReader streamReader = new StreamReader(memoryStream);
XmlSerializer serilazer = new XmlSerializer(typeof(T));
serilazer.Serialize(memoryStream,obj);
memoryStream.Position = 0;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(streamReader.ReadToEnd());
return xmlDoc;
}
}
}
使用代理类
function onGridCustomerUpdated(rowItem)
{
var customerProxy = new CustomerProxy();
customerProxy.onDeserialized = onServerCustomerUpdated;
customerProxy.onXmlDataLoaded = onShowResponseXml;
customerProxy.updateCustomer(rowItem.id,rowItem["Company Name"],
rowItem["Contact Name"], rowItem["Contact Title"],
rowItem["Address"] , rowItem["City"],rowItem["Region"],
rowItem["Postal Code"], rowItem["Country"] ,
rowItem["Phone"] , rowItem["Fax"]);
}
function onServerCustomerUpdated(result)
{
if(result!="true")
alert("Failure to save the data.");
}
onGridCustomerUpdated
是 grid.onRowUpdated
事件的处理程序。您可以在 Grid 的文章中找到关于 Grid 事件模型的所有信息。
链接
- JavaScript DataGrid
https://codeproject.org.cn/jscript/Javascript_DataGrid.asp - Web 服务
https://codeproject.org.cn/useritems/Data_Access_Object.asp
注意
请不要直接在您的项目中原封不动地使用此代码。这只是一个处理数据的演示版本,需要经过充分的测试。
如果您觉得这篇文章有趣,请为我投票。