asp.net 购物车的实现浅析

  该购物车的功能如下:

  . 通过ajax实现添加和删除车上的物品。

  . 删除的物品会显示出来,可以重新添加到购物车。

  . 嗯...没有了,具体大家接着看吧。

  购物车的结构我打算用一个table来展示,在UserControl里使用ListView展现购物车的物品(因为比拼接字符串要容易维护的多)。具体代码如下(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'>

  商品编号

  </td>

  <td>

  商品名称

  </td>

  <td width='10%'>

  京东价

  </td>

  <td width='8%'>

  返现

  </td>

  <td width='8%'>

  赠送积分

  </td>

  <td width='9%'>

  商品数量

  </td>

  <td width='7%'>

  删除商品

  </td>

  </tr>

  <tr runat="server" id="itemPlaceholder" />

  <tr>

  <td colspan='7' style='height: 30px'>

  重量总计:<%= this.GetProductsWeight() %>kg   原始金额:¥307.00元 - 返现:¥0.00元<br />

  <span style='font-size: 14px'><b>商品总金额(不含运费):<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>

  我想大家应不用我解释代码的意思了,很简单。

  后台代码如下:

  

复制代码 代码如下:

  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; }

  }

  把对购物车的逻辑都写到这里面,通过action来判断是什么操作,一样简单的代码。再来看看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新款轻巧便携式电脑桌(送鼠标垫)",Price="79.00",BackMoney="¥0.00",Score="0",Count="1"},

  new Product{ID="155098",Name="xxxxxx护眼台灯(理想)STL-T412W-03WT",Price="69.00",BackMoney="¥0.00",Score="0",Count="1"}

  };

  return list.Where(p => { return p.ID != productID; }).ToList();

  }

  }

  接下来在ShopCartDetail.aspx页面使用该UserControl:

  

复制代码 代码如下:

  <div id="products">

  <demo:ShopCartTest ID="ShopCartTest1" runat="server" />

  </div>

  通过ajax使用购物车还需要两个类:

  

复制代码 代码如下:

  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();

  }

  }

  这两个类是参考老赵提出来的方案完成,具体原理,你可以看这里。

  剩下来都是javascript了,这里我并没有使用任何类库或者框架。代码如下:

  

复制代码 代码如下:

  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 + "');\">重新购买</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) { }

  }

  代码依旧很容易看懂,需要解释的就是删除的操作,分为三步:

  将需要删除的物品先保存起来:setDelProduct(obj, productId);

  在后台购物车清单上面将物品删除,并返回删除后的物品清单:ajaxCommon("action=removeProductOnShoppingCart&productId=" + productId);

  将删除的物品输出,放到已删除列表(完全在客户端操作):setDelProductShow();

  还有从删除列表中将删除的物品重新添加到购物车当中,分为两步:

  在后台将物品添加到物品清单(和直接添加物品调用同一个方法):addProduct

  从已删除列表中将该物品删除(完全在客户端操作):reAddedProduct

  这样,一个基本的购物车就完成了。但是具体对于数据的操作,需要您进一步处理。本文对于数据的操作只是示例而已。