学习淘淘商城第十八课(商品分类选择的实现)

   上节课我们一起学习了怎样实现展示商品列表的功能,这节课我们一起学习下怎样实现商品分类的选择。

       首先,当然还是启动我们的zookeeper注册中心,然后启动taotao-manager工程和taotao-manager-web工程,启动后我们点击"新增商品",然后点击"选择类目",打开的对话框是空白的,没有任何信息。这是因为我们还没有实现该界面的展示。


        我们还是从index.jsp页面开始说起,如下图所示,可以看到当我们点击左侧菜单中的"新增商品"时,是会自动去请求item-add文件的。我们在第十六节课已经实现了展示后台界面的功能。


      我们下面来看看item-add.jsp界面代码,我们从中可以看到,这个页面其实也是个代码片段,"选择类目"按钮其实是个链接,样式为"easyui-linkbutton",我们会发现该链接并没有指定onclick事件,那么是怎样触发鼠标点击事件呢?其实是".selectItemCat"样式来处理的。我们在item-add.jsp当中搜索会发现并没有定义"selectItemCat",那么到底是在哪儿定义的呢?

[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
  2. <link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">  
  3. <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>  
  4. <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>  
  5. <div style="padding:10px 10px 10px 10px">  
  6.     <form id="itemAddForm" class="itemForm" method="post">  
  7.         <table cellpadding="5">  
  8.             <tr>  
  9.                 <td>商品类目:</td>  
  10.                 <td>  
  11.                     <a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">选择类目</a>  
  12.                     <input type="hidden" name="cid" style="width: 280px;"></input>  
  13.                 </td>  
  14.             </tr>  
  15.             <tr>  
  16.                 <td>商品标题:</td>  
  17.                 <td><input class="easyui-textbox" type="text" name="title" data-options="required:true" style="width: 280px;"></input></td>  
  18.             </tr>  
  19.             <tr>  
  20.                 <td>商品卖点:</td>  
  21.                 <td><input class="easyui-textbox" name="sellPoint" data-options="multiline:true,validType:'length[0,150]'" style="height:60px;width: 280px;"></input></td>  
  22.             </tr>  
  23.             <tr>  
  24.                 <td>商品价格:</td>  
  25.                 <td><input class="easyui-numberbox" type="text" name="priceView" data-options="min:1,max:99999999,precision:2,required:true" />  
  26.                     <input type="hidden" name="price"/>  
  27.                 </td>  
  28.             </tr>  
  29.             <tr>  
  30.                 <td>库存数量:</td>  
  31.                 <td><input class="easyui-numberbox" type="text" name="num" data-options="min:1,max:99999999,precision:0,required:true" /></td>  
  32.             </tr>  
  33.             <tr>  
  34.                 <td>条形码:</td>  
  35.                 <td>  
  36.                     <input class="easyui-textbox" type="text" name="barcode" data-options="validType:'length[1,30]'" />  
  37.                 </td>  
  38.             </tr>  
  39.             <tr>  
  40.                 <td>商品图片:</td>  
  41.                 <td>  
  42.                      <a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上传图片</a>  
  43.                      <input type="hidden" name="image"/>  
  44.                 </td>  
  45.             </tr>  
  46.             <tr>  
  47.                 <td>商品描述:</td>  
  48.                 <td>  
  49.                     <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea>  
  50.                 </td>  
  51.             </tr>  
  52.             <tr class="params hide">  
  53.                 <td>商品规格:</td>  
  54.                 <td>  
  55.                       
  56.                 </td>  
  57.             </tr>  
  58.         </table>  
  59.         <input type="hidden" name="itemParams"/>  
  60.     </form>  
  61.     <div style="padding:5px">  
  62.         <a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>  
  63.         <a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()">重置</a>  
  64.     </div>  
  65. </div>  
  66. <script type="text/javascript">  
  67.     var itemAddEditor ;  
  68.     //页面初始化完毕后执行此方法  
  69.     $(function(){  
  70.         //创建富文本编辑器  
  71.         itemAddEditor = TAOTAO.createEditor("#itemAddForm [name=desc]");  
  72.         //初始化类目选择和图片上传器  
  73.         TAOTAO.init({fun:function(node){  
  74.             //根据商品的分类id取商品 的规格模板,生成规格信息。第四天内容。  
  75.             //TAOTAO.changeItemParam(node, "itemAddForm");  
  76.         }});  
  77.     });  
  78.     //提交表单  
  79.     function submitForm(){  
  80.         //有效性验证  
  81.         if(!$('#itemAddForm').form('validate')){  
  82.             $.messager.alert('提示','表单还未填写完成!');  
  83.             return ;  
  84.         }  
  85.         //取商品价格,单位为“分”  
  86.         $("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100);  
  87.         //同步文本框中的商品描述  
  88.         itemAddEditor.sync();  
  89.         //取商品的规格  
  90.         /*  
  91.         var paramJson = [];  
  92.         $("#itemAddForm .params li").each(function(i,e){  
  93.             var trs = $(e).find("tr");  
  94.             var group = trs.eq(0).text();  
  95.             var ps = [];  
  96.             for(var i = 1;i<trs.length;i++){  
  97.                 var tr = trs.eq(i);  
  98.                 ps.push({  
  99.                     "k" : $.trim(tr.find("td").eq(0).find("span").text()),  
  100.                     "v" : $.trim(tr.find("input").val())  
  101.                 });  
  102.             }  
  103.             paramJson.push({  
  104.                 "group" : group,  
  105.                 "params": ps  
  106.             });  
  107.         });  
  108.         //把json对象转换成字符串  
  109.         paramJson = JSON.stringify(paramJson);  
  110.         $("#itemAddForm [name=itemParams]").val(paramJson);  
  111.         */  
  112.         //ajax的post方式提交表单  
  113.         //$("#itemAddForm").serialize()将表单序列号为key-value形式的字符串  
  114.         $.post("/item/save",$("#itemAddForm").serialize(), function(data){  
  115.             if(data.status == 200){  
  116.                 $.messager.alert('提示','新增商品成功!');  
  117.             }  
  118.         });  
  119.     }  
  120.       
  121.     function clearForm(){  
  122.         $('#itemAddForm').form('reset');  
  123.         itemAddEditor.html('');  
  124.     }  
  125. </script>  
       我们可以使用Ctrl+H来打开全文搜素对话框,在"File Search"一栏的上面那个输入框中输入我们想要搜素的内容,下面指定在哪些类型的文件中搜素,然后点击"Search"。

        搜索完之后,可以看到如下图所示的搜索结果,我们双击进去。

         可以看到在common.js文件中有关于".selectItemCat"的事件定义。那么大家可能也注意到了,在item-add.jsp页面当中并没有引用common.js文件,为何能使用这个js文件呢,其实很简单,这是因为在index.jsp页面中引用了该js文件,而item-add.jsp文件只是index.jsp的一个代码片段而已,因此可以直接使用Index.jsp引用的js文件。

        那么,这个分类选择按钮是什么时候被初始化的呢?我们可以从item-add.jsp下面的js中找到答案,如下图所示,可以看到,$(function){}是页面加载完之后会执行的脚本,在这里面有TAOTAO.init方法来初始化类目选择。那么这个TAOTAO又是在哪儿定义的呢?

        其实TAOTAO也是在common.js文件中定义的,如下所示,可以看到TAOTAO中定义了一个init方法,在该方法中调用了this.initItemCat(data);来初始化类选择组件。

      this.initItemCat(data);所对应的代码如下,我们可以看到$(".selectItemCat").each(function(i,e){这行代码,为何要用each来循环呢?这是因为使用.selectItemCat样式的地方可能不止一处,这样初始化就不能只初始化一处,而是应该把所有用到该样式的地方都进行初始化,i是遍历的第几个元素,e是指被遍历的对象,var _ele = $(e);的作用是把dom对象转换为jquery对象,这样就能直接使用jquery的方法了。_ele.unbind('click').click(function(){的意思是先进行解绑,然后再进行绑定,其中渲染了一个window窗口对象,设置了宽和高,modal:true;是指是否使用模态(就是我们打开对话框之后,后面是灰色的背景,不能操作,只能操作当前打开的对话框),true就是使用的意思。closed:true的意思是节点是否是闭合的,如果节点下面还有节点,那么默认就应该是闭合的,如果没有子节点了,那么就应该是展开的。onPen是当窗口要打开时候触发的函数,其中有url:'/item/cat/list',这句代码的意思是,会向url:'/item/cat/list',这个地址请求窗口中的数据源。

[html]  view plain  copy
  1. initItemCat : function(data){  
  2.         $(".selectItemCat").each(function(i,e){  
  3.             var _ele = $(e);  
  4.             if(data && data.cid){  
  5.                 _ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");  
  6.             }else{  
  7.                 _ele.after("<span style='margin-left:10px;'></span>");  
  8.             }  
  9.             _ele.unbind('click').click(function(){  
  10.                 $("<div>").css({padding:"5px"}).html("<ul>")  
  11.                 .window({  
  12.                     width:'500',  
  13.                     height:"450",  
  14.                     modal:true,  
  15.                     closed:true,  
  16.                     iconCls:'icon-save',  
  17.                     title:'选择类目',  
  18.                     onOpen : function(){  
  19.                         var _win = this;  
  20.                         $("ul",_win).tree({  
  21.                             url:'/item/cat/list',  
  22.                             animate:true,  
  23.                             onClick : function(node){  
  24.                                 if($(this).tree("isLeaf",node.target)){  
  25.                                     // 填写到cid中  
  26.                                     _ele.parent().find("[name=cid]").val(node.id);  
  27.                                     _ele.next().text(node.text).attr("cid",node.id);  
  28.                                     $(_win).window('close');  
  29.                                     if(data && data.fun){  
  30.                                         data.fun.call(this,node);  
  31.                                     }  
  32.                                 }  
  33.                             }  
  34.                         });  
  35.                     },  
  36.                     onClose : function(){  
  37.                         $(this).window("destroy");  
  38.                     }  
  39.                 }).window('open');  
  40.             });  
  41.         });  
  42.     },  
      那么服务器应该返回什么样的数据呢?我们从EasyUI的API中可以看到信息,大家可以到:http://download.csdn.net/detail/u012453843/9798148这个地址进行下载,下载后,我们打开如下部分,可以看到,返回的数据是对象的json数组,节点必须有的属性是id、text、state,children可有可无。id是是节点的ID,text是节点的名称,state是节点是否展开。


        下面我们来看看我们的数据库中存储商品分类的表以及存储的数据,如下图所示,可以看到该表有id、parent_id、name、status、sort_order、is_parent等字段,其中parent_id是用来表示树形关系的,is_parent表示是不是父节点,1表示是父节点,0表示是叶子节点。我们在上图中知道了要展示树形结构数据,需要有固定的三个字段,分别是id、text和state,那么对应到数据库中的字段便是id、name、is_parent三个字段。


         下面我们在taotao-common工程新建一个pojo类EasyUITreeNode,如下图所示,由于该类要在服务端和客户端之间传输,因此一定要实现序列化。


       写完了pojo类,我们再看看Dao层,由于是单表查询,因此我们使用逆向工程自动生成的代码就可以,因此Dao层不用写。

       既然Dao层不用写,我们直接看Service层,我们需要新建一个ItemCatService接口类并定义一个接口,如下图所示。


    下面我们来新建一个商品分类的实现类,如下图所示。


      由于新增了服务实现类,因此我们需要在applicationContext-service.xml文件中发布dubbo服务部分暴露一下接口。如下图所示。


      服务端写完之后,我们下面来写springmvc客户端,我们创建一个ItemCatController类,如下图所示。由于parentId与所传递过来的参数id名称不一致,因此需要使用@RequestParam(name="id")来关联起来,由于刚开始的时候是不传id参数的,因此需要给id一个默认值"0",也就是defaultValue="0"。


        在ItemCatController类中添加获取分类节点的方法,其中@RequestMapping("/item/cat/list")这个请求路径是从我们common.js的窗口打开事件中访问的地址复制而来的。如下图所示。



         我们还可以通过控制台提示的信息找到请求的路径,如下图所示。


         既然在服务端使用dubbo发布了ItemCatService服务,那么在客户端我们便需要使用dubbo引用下该服务,方法是在springmvc.xml文件中进行引用,如下图所示。


       重新打包taotao-common、taotao-manager-interface工程到本地仓库,方法:在工程上右键-------->Run As --------->Maven Install。

       重启taotao-manager和taotao-manager-web工程,这时再点击"选择类目",这时便可以看到商品分类了。如下图所示。


      我们可以点击下面的list请求,查看具体的请求及返回信息。我们发现第一次访问并没有带id的信息。


       当我们展开"钟表"分类时,如下图所示,可以看到,这次访问便带上了参数id=290,这个id是从表单直接传递过来的。


      这样我们便实现了商品分类的展示及选择。

版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值