SSH框架网上商城项目第28战之使用Ajax技术局部更新商品数量和总价

之前,把项目部署了一下,玩了玩,今天完善了一下购物车中修改商品数量就能局部更新相应的总价的功能,大家都知道这得用Ajax实现,我之前也没学Ajax,刚好借助这个小功能,去简单学习一下Ajax的知识。  

1. 问题的分析

先看一下页面中的情况:

功能如上,在没有Ajax之前,一般都是根据用户修改的值去找Action,然后返回新的jsp页面重新加载整个页面,完成数字的更新。但是有了Ajax技术后,我们可以利用Ajax技术局部刷新要改变的地方,而不是重新加载整个页面。首先看一下上图对应的jsp部分的代码:

<div class="section_container">
 <!-- 购物车 -->
 <div id="shopping_cart">
  <div class="message success">我的购物车</div>
   <table class="data-table cart-table" cellpadding="0" cellspacing="0">
    <tr>
     <th class="align_center" width="10%">商品编号</th>
     <th class="align_left" width="35%" colspan="2">商品名称</th>
     <th class="align_center" width="10%">销售价格</th>
     <th class="align_center" width="20%">数量</th>
     <th class="align_center" width="15%">小计</th>
     <th class="align_center" width="10%">删除</th>
    </tr>
    <c:forEach items="${sessionScope.forder.sorders }" var="sorder" varStatus="num">
    <tr lang="${sorder.product.id}">
     <td class="align_center"><a href="#" class="edit">${num.count }</a></td>
     <td width="80px"><img src="${shop}/files/${sorder.product.pic}" width="80" height="80" /></td>
     <td class="align_left"><a class="pr_name" href="#">${sorder.name }</a></td>
     <td class="align_center vline">${sorder.price }</td>
     <td class="align_center vline">
      <!-- 文本框 -->
      <input class="text" style="height: 20px;" value="${sorder.number }" lang="${sorder.number }">
     </td>
     <td class="align_center vline">${sorder.price*sorder.number }</td>
     <td class="align_center vline"><a href="#" class="remove"></a></td>
    </tr>
    </c:forEach>

   </table>
   <!-- 结算 -->
   <div class="totals">
    <table id="totals-table">
     <tbody>
      <tr>
       <td width="60%" colspan="1" class="align_left"><strong>小计</strong></td>
       <td class="align_right" style=""><strong>¥<span
          class="price" id="total">${sessionScope.forder.total}</span>
       </strong></td>
      </tr>
      <tr>
       <td width="60%" colspan="1" class="align_left">运费</td>
       <td class="align_right" style="">¥<span class="price" id="yunfei">0.00</span></td>
      </tr>
      <tr>
       <td width="60%" colspan="1" class="align_left total"><strong>总计</strong></td>
       <td class="align_right" style="">¥<span class="total" id="totalAll"><strong>${sessionScope.forder.total}</strong></span>
       </td>
      </tr>
     </tbody>
    </table>
    <div class="action_buttonbar">
     <font><a href="${shop}/user/confirm.jsp">
      <button type="button" title="" class="checkout fr" style="background-color: #f38256;">订单确认</button></a>
     </font>
     <font><a href="#">
      <button type="button" title="" class=" fr">
       <font>清空购物车</font>
      </button>
     </font>
     <a href="${shop}/index.jsp">
      <button type="button" title="" class="continue fr">
       <font>继续购物</font>
      </button></a>
     <div style="clear:both"></div>
    </div>
   </div>
  </div>

  看着貌似很多的样子,其实功能很简单,就是从域中拿出相应的数据显示出来而已,我们现在要实现上面描述的功能的话,先来分析一下思路:

首先得注册一个事件:即修改了数量那里的文本框触发的事件;
在该事件中,我们拿到用户输入的数,判断输入的合法性,因为要防止用户乱输入;
如果合法,通过Ajax请求将数据发送到后台;
后台针对新的数量,调用相应的业务逻辑方法得到新的结果,并将其通过流返回到前台;
Ajax收到结果后,再对相应位置的数据进行更新。整个流程就走完了。
如果非法,则显示修改前的数字。不做任何处理

2. Ajax请求的实现

分析完了流程,接下来我们就着手去实现了,首先把js部分的代码贴在这,然后我们根据上面的流程详细分析:

<script type="text/javascript">
 $(function(){
  //1. 注册事件
  $(".text").change(function(){
  //2. 验证数据的有效性
   var number = this.value; //也可以使用$(this).val();
   //isNaN(number)表示若number不是数字就返回真
   if(!isNaN(number) && parseInt(number)==number && number>0){
    //如果合法,同步更新的数
    $(this).attr("lang", number);
    //找到当前标签中第一个是tr的父节点,然后拿到属性为lang的值,也就是商品的id
    var pid = $(this).parents("tr:first").attr("lang");
    //发送Ajax请求,传输当前的数量与商品的id,返回修改数量后的总价格
    $.post("sorder_updateSorder.action",
     {number:number, 'product.id':pid},
     function(total){
      $("#total").html(total); //所有商品小计
      var yunfei = $("#yunfei").html();
      $("#totalAll").html((total*1 + yunfei*1).toFixed(2));//所有商品小计和运费的和
    }, "text");
    //计算单个商品的小计,保留两位小数
    var price = ($(this).parent().prev().html()*number).toFixed(2);
    $(this).parent().next().html(price);
   } else {
    //如果非法,还原为刚刚合法的数
    this.value = $(this).attr("lang");
   }
  })
 })
</script>

2.1 注册事件

  我们看上面的代码可知,注册事件首先要定位到这个文本框,这里是通过类选择器来定位的,因为是文本框,所以用change()来注册该事件,然后在里面定义一个function()函数来处理该事件。

2.2 判断数据合法性

  好了,注册好了事件后,我们首先要对用户输入的数进行合法性判断,因为用户可能输入了0或者负数,可能输入了小数,甚至输入了字母或其他字符等等。所以要进行验证。isNaN(number)表示若number不是数字就返回真,我们可以用这个函数来判断是否为数字;parseInt(number)表示对数组进行取整,然后跟它自身进行比较,我们巧妙的运用了这个来判断number是否为整数。

2.3 发送Ajax请求

  如果数据是合法的,我们获取该数据后,就可以向后台发送Ajax请求了,我们需要考虑一个问题:需要传哪些参数呢?首先用户想要更新数量,毫无疑问,用户输入的数字肯定要传过去,其次到底传哪个商品呢?也就是说我们需要获取用户想要修改的商品的id号,知道了要传的参数后,我们想办法获取id号即可。
  这里有一个问题,用户的购物车里可能不止一件商品,很自然的会想到,如果能用一条语句可以拿到不同商品的id,就非常好了,因此,想到了可以使用该文本框的父标签,因为不同的商品它的父标签都一样,都是第一个<tr>标签,所以我们把商品的id放在那个<tr>标签中的lang属性里,为什么要放在lang属性里呢?因为lang属性基本不会用到,它是用来定义语言的,而且用lang属性还不容易和其他属性冲突~这样我们就可以通过$(this).parents("tr:first").attr("lang");来获取商品的id了。
  接下来开始发送Ajax请求,使用post方式发送,post方法中有四个参数:

第一个参数是要发送到的Action
第二个参数是要传过去的参数,使用的是json格式
第三个参数是一个function(result),result是用来接收后台穿过来的数据
第四个方式是规定接收什么类型的数据,json表示接收json数据,text表示接收流

  从后台返回的total是所有商品的总价格,所以在function中,首先我们根据id拿到所有商品小计的元素然后赋值为total即可,totalAll是加了运费的总价,后面那个toFixes(2)表示保留两位小数。然后再拿到单个商品小计的元素,计算一下单个商品的小计,这样前台页面在没有重新载入的情况下,更新了我们想要更新的部分,这就是Ajax强大的地方,这个和前面EasyUI一样的,EasyUI也是Ajax请求。
   好了,关于Ajax部分到这里就介绍完了,下面是后台的处理刚刚的请求,是针对自己这个项目的,用来记录项目进度用的。

3. 后台的更新

  刚刚Ajax请求的action是SortedAction中的updateSorder()方法,所以我们去SorderAction中完成updateSorder()方法:

@Controller
@Scope("prototype")
public class SorderAction extends BaseAction<Sorder> {
 public String addSorder() {

 //省略无关的代码……

 //根据商品编号更新商品数量
 public String updateSorder() {
  Forder forder = (Forder) session.get("forder");
  //更新购物项,传进来的product.id被封装到了model中
  forder = sorderService.updateSorder(model, forder);
  //计算新的总价格
  forder.setTotal(forderService.cluTotal(forder));
  session.put("forder", forder);
  //以流的形式返回新的总价格
  inputStream = new ByteArrayInputStream(forder.getTotal().toString().getBytes());
  return "stream";
 }
}

相应的Service中的方法完善如下:

//SorderService接口
public interface SorderService extends BaseService<Sorder> {
 //省去无关的代码……
 //根据商品id和数量更新商品数量
 public Forder updateSorder(Sorder sorder, Forder forder);
}

//SorderServiceImpl实现类
@Service("sorderService")
public class SorderServiceImpl extends BaseServiceImpl<Sorder> implements
  SorderService {

 //省略无关的代码……

 @Override
 public Forder updateSorder(Sorder sorder, Forder forder) {
  for(Sorder temp : forder.getSorders()) {
   if(temp.getProduct().getId().equals(sorder.getProduct().getId())) {
    temp.setNumber(sorder.getNumber());
   }
  }
  return forder;
 }
}

最后struts.xml文件中的配置,是把”stream”配在了<global-result>里面,如下

<global-results>
  <!-- 省去其他公共配置 -->
  <result name="stream" type="stream">
   <param name="inputName">inputStream</param>
  </result>
</global-results>

好了,现在Action中计算出的总价格就可以通过流的形式传到前台了,Ajax就可以在它的function中接收到,放到total中了,跟前面的就接上了。

原文链接: http://blog.csdn.net/eson_15/article/details/51487323

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android仿美团下拉菜单(商品选购)实例代码

    美团电商应用平台大家使用非常频繁,下面小编通过本文给大家介绍电商应用平台中常用的选择类别下拉列表的实现.先给大家展示下效果图: 一.下拉列表的实现 其实实现方法有很多,这时实现的也没有什么技术含量,只是总结下自己在项目中的做法,也提供一个思路. 首先是列表的数据,一般数据都是从后台读过来,这里因为没有后台,所以写死在客户端: private void initMenuData() { menuData = new ArrayList<map<string, string=""

  • Android仿淘宝商品浏览界面图片滚动效果

    用手机淘宝浏览商品详情时,商品图片是放在后面的,在第一个ScrollView滚动到最底下时会有提示,继续拖动才能浏览图片.仿照这个效果写一个出来并不难,只要定义一个Layout管理两个ScrollView就行了,当第一个ScrollView滑到底部时,再次向上滑动进入第二个ScrollView.效果如下: 需要注意的地方是: 1.如果是手动滑到底部需要再次按下才能继续往下滑,自动滚动到底部则不需要 2.在由上一个ScrollView滑动到下一个ScrollView的过程中多只手指相继拖动也不会导

  • Android自定义商品购买数量加减控件

    在购买商品时,大家可以自定义数字加减控件,来确定购买商品的实际数量,如何实现此控件,请参考下文: 1.自定义数字加减控件的要求 创建Module -NumberAddSubView A_输入的只能是数字,而且不能通过键盘输入 B_通过加减按钮操作数字 C_监听加减按钮 D_数组有最小值和最大值的限制 E_自定义属性 2.提供接口,让外界监听到数字的变化 1_设置接口 @Override public void onClick(View v) { if (v.getId() == R.id.btn

  • Android仿淘宝商品拖动查看详情及标题栏渐变功能

    绪论 最近一直比较忙,也没抽出时间来写博客,也不得不说是自己犯了懒癌,人要是一懒就什么事都不想做了,如果不能坚持下来的话,那么估计就废了,��.最近自己攒了好多东西,接下来的时间我会慢慢都分享出来的.好了废话不多说了,下面我们开始正题: 今天要分享的是淘宝的详情页,之前在淘宝上买东西的时候看到淘宝的详情页效果比较不错,所以今天就来仿一下它的效果吧,可能没有淘宝的好,希望见谅啊. 先上效果图: 这是淘宝的: 我自己做的: 怎么样效果还差不多吧?GIF图效果看的不太清楚,见谅. 下面我们来看看怎么实

  • Android实现仿淘宝购物车增加和减少商品数量功能demo示例

    本文实例讲述了Android实现仿淘宝购物车增加和减少商品数量功能.分享给大家供大家参考,具体如下: 在前面一篇<Android实现的仿淘宝购物车demo示例>中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了,本来想买一件来着,小手不小心抖了一下,把数量错点成了三个,这个时候就涉及到一个新的功能,那就是增加和减少商品的数量,今天这篇博文,小编就来和小伙伴们

  • 安卓(android)仿电商app商品详情页按钮浮动效果

    1.效果图如下: 这效果用户体验还是很酷炫,今天我们就来讲解如何实现这个效果. 2.分析 为了方便理解,作图分析 如图所示,整个页面分为四个部分: 1.悬浮内容,floatView 2.顶部内容,headView 3.中间内容,与悬浮内容相同,middleView 4.商品详情展示页面,detailView 因为页面内容高度会超出屏幕,所以用Scrollview实现滚动,悬浮view与scrollview同级,都在一个帧布局或者相对布局中. 当y方向的滚动距离小于中间的内容middleView到

  • 妙用Ajax技术实现局部刷新商品数量和总价实例代码

    1. 问题的分析 先看一下页面中的情况: 功能如上,在没有Ajax之前,一般都是根据用户修改的值去找Action,然后返回新的jsp页面重新加载整个页面,完成数字的更新.但是有了Ajax技术后,我们可以利用Ajax技术局部刷新要改变的地方,而不是重新加载整个页面.首先看一下上图对应的jsp部分的代码: <div class="section_container"> <!-- 购物车 --> <div id="shopping_cart"

  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解

    一.淘宝商品详情页效果 我们的效果 二.实现思路 使用两个scrollView,两个scrollView 竖直排列,通过自定义viewGroup来控制两个scrollView的竖直排列,以及滑动事件的处理.如下图 三.具体实现 1.继承viewGroup自定义布局View 重写onMeasure()和onLayout方法,在onLayout方法中完成对两个子ScrollView的竖直排列布局,代码如下: 布局文件: <RelativeLayout xmlns:android="http:/

  • Android实现淘宝选中商品尺寸的按钮组实例

    话不多说,先上个效果图: 现在我们就来说说里面的一些原理把! 一.原理: 1.其实这里我们用到的是一个ViewGroup控件组,把这些按钮加进去就有这种效果了!不过这里要继承ViewGroup(命名为:GoodsViewGroup)重写里面的一些方法. 2.主要的方法有: GoodsViewGroup按钮组的控件大小 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 里面的按钮每个的位置坐标 protect

  • JavaScript实现仿淘宝商品购买数量的增减效果

    近期在开发一个地方O2O租书项目,使用ASP.NET MVC技术,其中在图书详情页,用户可以输入借阅的数量,这里使用了js来控制数量的增减和校验. 1.数量一定是数字 2.点击增减按钮的时候要能自动加1或减1 3.用户输入的内容如果是非数字,则不能输入(退格键除外) 4.用户输入的值最小为1 5.输入框离开焦点时要检查取值范围,确保输入框中必须是范围内的数字 基本就是以上几点 效果如下: 以下是Html代码 <div class="bookNum"> <a id=&q

随机推荐