asp.net 購(gòu)物車的實(shí)現(xiàn)淺析
. 通過(guò)ajax實(shí)現(xiàn)添加和刪除車上的物品。
. 刪除的物品會(huì)顯示出來(lái),可以重新添加到購(gòu)物車。
. 嗯...沒(méi)有了,具體大家接著看吧。
購(gòu)物車的結(jié)構(gòu)我打算用一個(gè)table來(lái)展示,在UserControl里使用ListView展現(xiàn)購(gòu)物車的物品(因?yàn)楸绕唇幼址菀拙S護(hù)的多)。具體代碼如下(ShopCartTest.ascx):
<asp:ListView ID="ListView1" runat="server">
<LayoutTemplate>
<table runat="server" cellpadding='0' cellspacing='0' width='100%'>
<tr>
<td width='7%' style='height: 30px'>
商品編號(hào)
</td>
<td>
商品名稱
</td>
<td width='10%'>
京東價(jià)
</td>
<td width='8%'>
返現(xiàn)
</td>
<td width='8%'>
贈(zèng)送積分
</td>
<td width='9%'>
商品數(shù)量
</td>
<td width='7%'>
刪除商品
</td>
</tr>
<tr runat="server" id="itemPlaceholder" />
<tr>
<td colspan='7' style='height: 30px'>
重量總計(jì):<%= this.GetProductsWeight() %>kg 原始金額:¥307.00元 - 返現(xiàn):¥0.00元<br />
<span style='font-size: 14px'><b>商品總金額(不含運(yùn)費(fèi)):<span id='cartBottom_price'>¥307.00</span>元</b></span>
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td style='padding: 5px 0 5px 0;'>
<%#(Container.DataItem as Product).ID %>
</td>
<td>
<a target='_blank' href='http://www.xxx.com/product/<%#(Container.DataItem as Product).ID %>.html'>
<%#(Container.DataItem as Product).Name %></a>
</td>
<td>
<span>
<%#(Container.DataItem as Product).Price %></span>
</td>
<td>
<%#(Container.DataItem as Product).BackMoney %>
</td>
<td>
<%#(Container.DataItem as Product).Score %>
</td>
<td>
<a href='#none' title='減一' onclick="changeCount('-','<%#(Container.DataItem as Product).ID %>','sku');"
style='text-decoration: none'>-</a><input type='text' id='txt<%#(Container.DataItem as Product).ID %>'
name='txtChange<%#(Container.DataItem as Product).ID %>' maxlength='4' style='width: 30px'
value='<%#(Container.DataItem as Product).Count %>' /><a href='#none' title='加一'
onclick="changeCount('+','<%#(Container.DataItem as Product).ID %>');" style='text-decoration: none'>+</a>
</td>
<td>
<a href='#none' id='btn_del_173259' onclick="removeProductOnShoppingCart('<%#(Container.DataItem as Product).ID %>',this)">
刪除</a>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
我想大家應(yīng)不用我解釋代碼的意思了,很簡(jiǎn)單。
后臺(tái)代碼如下:
public partial class ShopCartTest : System.Web.UI.UserControl
{
List<Product> productsList = null;
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
switch (Acion)
{
case "removeProductOnShoppingCart":
productsList = Product.GetProductsInCart(ProductID);
break;
case "changeProductCount":
productsList = Product.GetProductsInCart(null);
foreach (var item in productsList)
{
if (item.ID == ProductID)
{
item.Count = "3";
}
}
break;
case "AddProduct":
productsList = Product.GetProductsInCart(null);
productsList.Add(new Product() { ID = "173233", Name = "ElandMX9470", Price = "399.00", BackMoney = "0.00", Score = "0", Count = "1" });
break;
default:
productsList = Product.GetProductsInCart(ProductID);
break;
}
ListView1.DataSource = productsList;
ListView1.DataBind();
}
public string GetProductsWeight()
{
return Product.GetProductsInCart(ProductID).Sum(p => decimal.Parse(p.Price) * decimal.Parse(p.Count)).ToString();
}
public string GetProductsOriginalPrice()
{
return Product.GetProductsInCart(ProductID).Sum(p => decimal.Parse(p.Price) * decimal.Parse(p.Count)).ToString();
}
public string ProductID { get; set; }
public string Acion { get; set; }
}
把對(duì)購(gòu)物車的邏輯都寫到這里面,通過(guò)action來(lái)判斷是什么操作,一樣簡(jiǎn)單的代碼。再來(lái)看看Product類:
public class Product
{
public string ID { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public string BackMoney { get; set; }
public string Score { get; set; }
public string Count { get; set; }
public static List<Product> GetProductsInCart(string productID)
{
List<Product> list = new List<Product>()
{
new Product{ID="173259",Name="毛毛仔妮妮熊MX9470",Price="99.00",BackMoney="0.00",Score="0",Count="1"},
new Product{ID="155097",Name="xxxxxx新款輕巧便攜式電腦桌(送鼠標(biāo)墊)",Price="79.00",BackMoney="¥0.00",Score="0",Count="1"},
new Product{ID="155098",Name="xxxxxx護(hù)眼臺(tái)燈(理想)STL-T412W-03WT",Price="69.00",BackMoney="¥0.00",Score="0",Count="1"}
};
return list.Where(p => { return p.ID != productID; }).ToList();
}
}
接下來(lái)在ShopCartDetail.aspx頁(yè)面使用該UserControl:
<div id="products">
<demo:ShopCartTest ID="ShopCartTest1" runat="server" />
</div>
通過(guò)ajax使用購(gòu)物車還需要兩個(gè)類:
public class GetProducts : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
ViewManager<ShopCartTest> viewManager = new ViewManager<ShopCartTest>();
ShopCartTest control = viewManager.LoadViewControl("~/ShopCartTest.ascx");
control.ProductID = context.Request.QueryString["productId"];
control.Acion = context.Request.QueryString["action"];
context.Response.Write(viewManager.RenderView(control));
}
public bool IsReusable
{
get
{
return false;
}
}
}
public class ViewManager<T> where T : UserControl
{
private Page m_pageHolder;
public T LoadViewControl(string path)
{
m_pageHolder = new Page();
return this.m_pageHolder.LoadControl(path) as T;
}
public string RenderView(T control)
{
StringWriter output = new StringWriter();
this.m_pageHolder.Controls.Add(control);
HttpContext.Current.Server.Execute(this.m_pageHolder, output, false);
return output.ToString();
}
}
這兩個(gè)類是參考老趙提出來(lái)的方案完成,具體原理,你可以看這里。
剩下來(lái)都是javascript了,這里我并沒(méi)有使用任何類庫(kù)或者框架。代碼如下:
function ajaxCommon(requst) {
2 var xmlHttp = false;
3 if (window.ActiveXObject) {
4 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
5 }
6 else {
7 if (window.XMLHttpRequest) {
8 xmlHttp = new XMLHttpRequest();
9 }
}
xmlHttp.onreadystatechange = function() { getAjaxValue(xmlHttp) }
xmlHttp.open("GET", "/GetProducts.ashx" + '?roid=' + Math.random() + '&' + requst);
xmlHttp.send(null);
}
function getAjaxValue(xmlHttp) {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
document.getElementById("products").innerHTML = xmlHttp.responseText;
}
}
}
function addProduct(productID, productCount) {
ajaxCommon("action=AddProduct&productId=" + productID + "&productCount=" + productCount);
}
function removeProductOnShoppingCart(productId, obj) {
debugger;
setDelProduct(obj, productId);
ajaxCommon("action=removeProductOnShoppingCart&productId=" + productId);
setDelProductShow();
}
function changeCount(type, productID) {
var changeCount = 0;
var txtCount = 0;
if (type == "-") {
changeCount = -1;
}
if (type == "+") {
changeCount = 1;
}
txtCount = document.getElementById("txt" + productID).value;
ajaxCommon("action=changeProductCount&productId=" + productID + "&productCount=" + txtCount);
}
function DeledProductInfo() {
this.ID = '';
this.Name = '';
this.Price = '';
this.Count = '';
}
var delProduct = null;
function setDelProduct(obj, productID) {
try {
delProduct = new DeledProductInfo();
var trObj = obj.parentNode.parentNode;
delProduct.ID = trObj.cells[0].innerHTML;
delProduct.Name = trObj.cells[1].innerHTML;
delProduct.Price = trObj.cells[2].innerHTML;
delProduct.Count = document.getElementById('txt' + productID).value;
} catch (e) { }
}
function setDelProductShow() {
try {
if (document.getElementById('divDeledProduct') == null) return;
if (delProduct != null && delProduct.ID != '') {
var dHtml = "<table><tr>";
dHtml += "<td style='width:70px'>" + delProduct.ID + "</td>";
dHtml += "<td style='text-align:left'>" + delProduct.Name + "</td>";
dHtml += "<td>" + delProduct.Price + "</td>";
dHtml += "<td>" + delProduct.Count + "</td>";
dHtml += "<td><a href='#none' onclick=\"addProduct('" + delProduct.ID + "','" + delProduct.Count + "');reAddedProduct('delProduct" + delProduct.ID + "');\">重新購(gòu)買</a></td>";
dHtml += "</tr></table>";
document.getElementById('divDeledProduct').style.display = '';
document.getElementById('divDeledProduct').innerHTML += "<div id='delProduct" + delProduct.ID + "'>" + dHtml + "</div>";
}
delProduct = null;
} catch (e) { }
}
function reAddedProduct(reAddDivId) {
try {
debugger;
document.getElementById('divDeledProduct').removeChild(document.getElementById(reAddDivId));
if (document.getElementById('divDeledProduct').childNodes.length == 0) {
document.getElementById('divDeledProduct').style.display = 'none';
}
} catch (e) { }
}
代碼依舊很容易看懂,需要解釋的就是刪除的操作,分為三步:
將需要?jiǎng)h除的物品先保存起來(lái):setDelProduct(obj, productId);
在后臺(tái)購(gòu)物車清單上面將物品刪除,并返回刪除后的物品清單:ajaxCommon("action=removeProductOnShoppingCart&productId=" + productId);
將刪除的物品輸出,放到已刪除列表(完全在客戶端操作):setDelProductShow();
還有從刪除列表中將刪除的物品重新添加到購(gòu)物車當(dāng)中,分為兩步:
在后臺(tái)將物品添加到物品清單(和直接添加物品調(diào)用同一個(gè)方法):addProduct
從已刪除列表中將該物品刪除(完全在客戶端操作):reAddedProduct
這樣,一個(gè)基本的購(gòu)物車就完成了。但是具體對(duì)于數(shù)據(jù)的操作,需要您進(jìn)一步處理。本文對(duì)于數(shù)據(jù)的操作只是示例而已。
相關(guān)文章
Remoting和Webservice的詳細(xì)介紹及區(qū)別
這篇文章主要介紹了Remoting和Webservice的詳細(xì)介紹及區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-11-11微信公眾平臺(tái)開發(fā)之認(rèn)證"成為開發(fā)者".Net代碼解析
這篇文章主要為大家詳細(xì)解析了微信公眾平臺(tái)開發(fā)之認(rèn)證"成為開發(fā)者".Net代碼,感興趣的小伙伴們可以參考一下2016-06-06從客戶端檢測(cè)到有潛在危險(xiǎn)的Request.Form值的asp.net代碼
asp.net開發(fā)中,經(jīng)常遇到“從客戶端檢測(cè)到有潛在危險(xiǎn)的Request.Form 值”錯(cuò)誤提示,很多人給出的解決方案是2009-03-03asp.net實(shí)現(xiàn)非常實(shí)用的自定義頁(yè)面基類(附源碼)
這篇文章主要介紹了asp.net實(shí)現(xiàn)非常實(shí)用的自定義頁(yè)面基類,包含日志處理、控件賦值、異常處理等功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-11-11ASP.NET Session會(huì)導(dǎo)致的性能問(wèn)題
你的站點(diǎn)有被客戶投訴很慢嗎?是不是查了很多遍還是沒(méi)有完全解決?是不是數(shù)據(jù)庫(kù)沒(méi)有發(fā)現(xiàn)異常,CPU也沒(méi)有異常,內(nèi)存占用量沒(méi)有異常,GC計(jì)數(shù)沒(méi)有異常,硬盤IO也沒(méi)有異常,帶寬沒(méi)有異常,線路沒(méi)有異常,沒(méi)有丟包,但就是被投訴?2009-07-07詳解ASP.NET-----Repeater數(shù)據(jù)控件的用法總結(jié)
本篇文章主要介紹了ASP.NET--Repeater數(shù)據(jù)控件的用法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。2016-11-11Asp.net Mvc 身份驗(yàn)證、異常處理、權(quán)限驗(yàn)證(攔截器)實(shí)現(xiàn)代碼
本問(wèn)主要介紹asp.net的身份驗(yàn)證機(jī)制及asp.net MVC攔截器在項(xiàng)目中的運(yùn)用。現(xiàn)在讓我們來(lái)模擬一個(gè)簡(jiǎn)單的流程:用戶登錄》權(quán)限驗(yàn)證》異常處理2012-10-10Asp.Net Core使用swagger生成api文檔的完整步驟
這篇文章主要給大家介紹了關(guān)于Asp.Net Core使用swagger生成api文檔的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Asp.Net Core具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12