在线购物已经变得很平常了,而在使用购物车的时候,用户期望在其身上能够获得(足够的)灵活性。看看你能够如何把ASP和XML结合起来提供所用户需要的功能。
创建虚拟购物车的方法从来都不是单一的。最近,我碰到一个机会重新编写了一个经典的ASP购物车,让它成为一个拥有与原来类似的外观和感觉,但是更加灵活和更加快速的购物车。我决定利用XML,并开发一个跨浏览器的解决方案。现在让我来告诉你我自己碰到的一些问题,以及我是如何改进原有设计的。
原来的购物车
由于原来的购物车是针对特定的一组客户的,所以它更多地依赖于对用户的培训而非易用性。除了完全清空购物车,没有其他的机制用来对(所购的)内容进行更改。如果你往购物车里放入了错误的东西或者错误的数量,你不得不从头开始才能够更正这一错误。
而不为人知的是,原来的购物车再也无法变得更好。有限数量的行被显示出来,而客户会一页一页地翻阅购物车里的内容。这种方法的问题是,所有的东西都被保存在一个以ASP会话ID为基础的表格里。当客户浏览购物车内容的时候,就会进行一次查询。此外,如果会话超时,购物车的内容将会一直保留在表格里,直到有人手动删除它。
新的方法
我不想重复以前的错误,所以新的购物车将会基于XML会话而不会基于表格。这种方法有多个好处。首先,整个购物车以XML数据岛(Data Island)的形式保存在客户端上,如下面列表A所示。在进行简单浏览的时候,这就不再需要对表格进行查询了。但是用到了MozillaDSO()和xmlPage()函数。
列表A
<row>
<selected></selected>
<line>2</line>
<quantity>2</quantity>
<item>W02</item>
<description>Hand-and-a-half sword</description>
<weight>5.8</weight>
<unitprice>250.95</unitprice>
</row>
<row>
<selected></selected>
<line>3</line>
<quantity>1</quantity>
<item>W03</item>
<description>Wood long bow</description>
<weight>2.7</weight>
<unitprice>190.00</unitprice>
</row>
<row>
<selected></selected>
<line>4</line>
<quantity>1</quantity>
<item>W04</item>
<description>Wizard staff</description>
<weight>3.1</weight>
<unitprice>89.25</unitprice>
</row>
<row>
<selected></selected>
<line>5</line>
<quantity>1</quantity>
<item>C01</item>
<description>Gauntlets</description>
<weight>0.7</weight>
<unitprice>25.00</unitprice>
</row>
<row>
<selected></selected>
<line>6</line>
<quantity>5</quantity>
<item>C02</item>
<description>Knee-high boots</description>
<weight>1.9</weight>
<unitprice>95.00</unitprice>
</row>
<row>
<selected></selected>
<line>7</line>
<quantity>9</quantity>
<item>C04</item>
<description>Cloak</description>
<weight>1.0</weight>
<unitprice>125.00</unitprice>
</row>
<row>
<selected></selected>
<line>8</line>
<quantity>22</quantity>
<item>C05</item>
<description>Orc repellent</description>
<weight>1.0</weight>
<unitprice>8.95</unitprice>
</row>
<row>
<selected></selected>
<line>9</line>
<quantity>1</quantity>
<item>W05</item>
<description>Dwarf axe</description>
<weight>8.0</weight>
<unitprice>358.95</unitprice>
</row>
<row>
<selected></selected>
<line>10</line>
<quantity>1</quantity>
<item>A01</item>
<description>Steel cap</description>
<weight>2.8</weight>
<unitprice>219.95</unitprice>
</row>
<row>
<selected></selected>
<line>11</line>
<quantity>1</quantity>
<item>A02</item>
<description>Chainmail shirt</description>
<weight>15.3</weight>
<unitprice>487.22</unitprice>
</row>
<row>
<selected></selected>
<line>12</line>
<quantity>1</quantity>
<item>A03</item>
<description>Mithril shirt</description>
<weight>0.4</weight>
<unitprice>87236.03</unitprice>
</row>
<row>
<selected></selected>
<line>13</line>
<quantity>1</quantity>
<item>W07</item>
<description>Elvish long sword</description>
<weight>1.9</weight>
<unitprice>794.99</unitprice>
</row>
<row>
<selected></selected>
<line>14</line>
<quantity>1</quantity>
<item>W08</item>
<description>Elvish short sword</description>
<weight>0.8</weight>
<unitprice>435.99</unitprice>
</row>
<row>
<selected></selected>
<line>15</line>
<quantity>3</quantity>
<item>W09</item>
<description>Short sword</description>
<weight>1.5</weight>
<unitprice>89.95</unitprice>
</row>
</root>
除了浏览,xmlPage()方法还提供了原来的购物车不具备的功能——更改数量和删除物品的能力。由于它使用了两个XML数据岛——一个是绑定,另一个是非绑定——所以对绑定数据岛的更改不会影响到非绑定数据岛,直到点击更新键。一旦更新按钮被点击,就会有一种机制,比如XMLHTTP,把变化传送给服务器。如果由于某种原因你无法完全信任微软Internet Explorer和Mozilla里的XMLHTTP,那么一个带有隐藏式框架(例如iframe)和输入框的表单可以被用来实现同样的目的。下面的列表B显示了更新函数背后的JavaScript。
列表B
Island changes to the full Data Island. This is
accomplished by matching line numbers in both Data
Islands. Once this has been completed the full Data
Island is sent to the server via XMLHTTP.
Update Date: Programmer: Description:
*/
var objXMLHTTP;
// XMLHTTP request object
var reWork = new RegExp('internet explorer','gi');
document.body.style.cursor = 'wait'; // Set cursor
for(var i=0;i < objPage.bound.getElementsByTagName('row').length;i++)
for(var j=0;j < objPage.full.getElementsByTagName('row').length;j++)
if(objPage.bound.getElementsByTagName('line').item(i).firstChild.nodeValue == objPage.full.getElementsByTagName('line').item(j).firstChild.nodeValue) {
for(var k=0;k < objPage.bound.getElementsByTagName('row').item(i).childNodes.length;k++)
if(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName != '#text')
switch(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName.toLowerCase()) {
case('quantity'):
case('selected'):
try {
objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).firstChild.nodeValue = objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.nodeValue;
}
catch(e) {
try {
objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).appendChild(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.cloneNode(true));
}
catch(e) { }
}
break;
}
break;
}
// Send updates
if(reWork.test(navigator.appName))
objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');
else
objXMLHTTP = new XMLHttpRequest();
objXMLHTTP.open('GET','xmlServer.asp',true);
objXMLHTTP.setRequestHeader('content-type','text/xml');
objXMLHTTP.onreadystatechange = function() {
var reWork = new RegExp('internet explorer','gi');
if(objXMLHTTP.readyState == 4) {
if(reWork.test(navigator.appName))
objPage.full.XMLDocument.loadXML(unescape(objXMLHTTP.responseText));
else
objPage.full.innerHTML = unescape(objXMLHTTP.responseText);
//Handle empty page
if(objPage.page() > objPage.pagecount())
objPage.showPrevious();
else
objPage.showPage();
// Display page info
document.getElementById('currentpage').lastChild.nodeValue = objPage.page();
document.getElementById('totalpages').lastChild.nodeValue = objPage.pagecount();
document.body.style.cursor = 'auto';
} }
// IE work around
try {
objPage.full.innerHTML = objPage.full.XMLDocument.xml;
}
catch(e) { }
if(reWork.test(navigator.appName))
objXMLHTTP.setRequestHeader('request',escape(objPage.full.XMLDocument.xml));
else
objXMLHTTP.setRequestHeader('request',escape(objPage.full.innerHTML));
objXMLHTTP.send(null);
}
在做进一步讲解之前,我会在同一个句子里使用Mozilla和XMLHTTP。有书面的证据表明Mozilla支持XMLHTTP。尽管其句法与Internet Explorer所用的句法稍有不同,但这并不是JavaScript无法处理的东西。完整的客户端解决方案见图A,而ASP见下面的列表C。
发表回复