複習電商筆記-9
後臺首頁
通用的頁面跳轉
package com.jt.manage.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; /** * 通用的頁面跳轉控制器 */ @RequestMapping(value = "/page") @Controller public class PageController { @RequestMapping(value = "/{pageName}") public String toPage(@PathVariable("pageName") String pageName) { return pageName; } }
RESTFul方式請求
EasyUI富客戶端
jQuery EasyUI 提供了用於建立跨瀏覽器網頁的完整的元件集合,包括功能強大的 datagrid(資料網格)、treegrid(樹形表格)、 panel(面板)、combo(下拉組合)等等。 使用者可以組合使用這些元件,也可以單獨使用其中一個。
外掛列表如下:
分類 |
外掛 |
Base |
|
Layout(佈局) |
|
Menu(選單)與 Button(按鈕) |
|
Form(表單) |
|
Window(視窗) |
|
DataGrid(資料網格)與 Tree(樹) |
|
執行過程:
頁面控制:通過在div等標籤上加特定的屬性,引入easyUI js後,通過js進行相應的處理。或渲染,或者進行資料判斷等等。
資料控制:頁面通過ajax提交,在controller中準備資料,形成json串格式,返回頁面,EasyUI拿到資料json串,利用自身提供的js函式來渲染EasyUI元件。
引入js支援:
<link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<link rel="stylesheet" type="text/css" href="/js/jquery-easyui-1.4.1/themes/icon.css" />
<script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
佈局layout
<body class="easyui-layout">
<div data-options="region:'west',title:'選單',split:true" style="width:180px;"></div>
<div data-options="region:'center',title:''"></div>
</body>
選單menu
ul和li組合形成多級結構
<ul id="menu" class="easyui-tree">
<li>
<span>第一級選單</span>
<ul>
<li data-options="attributes:{'url':'/page/item-add'}">新增商品</li>
</ul>
</li>
</ul>
頁夾Tabs
點選自動建立一個新頁夾,頁夾之間可以隨意切換
<div id="tabs" class="easyui-tabs">
<div title="首頁" style="padding:20px;">
</div>
</div>
注意:iframe。如果多個表格控制元件時,它們的值POST發生衝突。引數同名。修改成不同名稱。
彈出視窗Window
$("<div>").css({padding:"5px"}).html("<ul>")
.window().window('open');
$(this).window("destroy");
點選自動建立一個新頁夾,頁夾之間可以隨意切換。
樹形元件Tree
$("ul",_win).tree({(url:ajax訪問連結)
連結按鈕
<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>
提示框
$.messager.alert('提示','表單還未填寫完成!');
頁面校驗
頁面加了校驗EasyUI(在表單的元素上增加屬性,提交時,被js方法攔截,按特殊的屬性進行校驗,校驗通過繼續提交到後臺,如果校驗失敗,在對應的元素後面增加錯誤提示。)
例如:商品資訊的校驗
標題 |
class="easyui-textbox" data-options="required:true" 必填 |
賣點 |
class="easyui-textbox" data-options="multiline:true,validType:'length[0,150]'" |
價格 |
class="easyui-numberbox" data-options="min:1,max:99999999,precision:2,required:true" |
庫存數量 |
class="easyui-numberbox" data-options="min:1,max:99999999,precision:0,required:true" |
條形碼 |
class="easyui-textbox" data-options="validType:'length[1,30]'" |
提交 |
class="easyui-linkbutton" onclick="submitForm()" |
實現商品分類樹功能
拷貝後臺資源
連結:https://pan.baidu.com/s/1w1YzPedd_s9m-_WzqKpDpA
提取碼:9d1l
連結:https://pan.baidu.com/s/1GEQZwqYzGG97vsxwdxBSUg
提取碼:72s1
表設計
EasyUI非同步載入樹要求
- id: 節點id,它是重要的來載入遠端資料
- text: 節點文字來顯示
- state: 節點狀態,“open”或“closed”,預設是“open”。當設定為“closed”,節點有子節點,並將負載從遠端站點
需要POJO物件增加兩個屬性,以滿足返回的json格式要求
// 擴充套件get方法,滿足EasyUI的tree格式
public String getText() {
return getName();
}
public String getState() {
return getIsParent() ? "closed" : "open";
}
EasyUI非同步載入樹工作原理
使用者建立一個空的樹,然後指定一個伺服器端動態返回JSON資料用來填充樹與非同步和需求。子節點載入依賴父節點狀態。當擴充套件一個封閉的節點,如果節點沒有子節點載入,它將傳送節點id的值作為http請求引數命名為“id”到伺服器上面定義通過URL檢索的子節點。
商品分類樹載入執行過程
使用者點選EasyUI的selectItemCat按鈕,呼叫頁面載入時的jQuery的KindEditorUtil.init()方法,KindEditorUtil為在common.js中定義的js物件。在init方法中呼叫this.initItemCat(data)。Each遍歷找到selectItemCat元素,給其繫結onclick事件,onclick事件中建立window視窗,在視窗的ul上載入EasyUITree。非同步post提交,通過url(/item/cat/list)指定呼叫路徑,通過註解找到ItemCatController,執行它的queryList方法,controller中呼叫service層,執行ItemCatService的queryListById方法,service中呼叫mybatis的mapper介面,呼叫 queryListById方法,其執行ItemCatMapper.xml檔案中配置的queryListById。執行SQL語句。查詢後返回ItemCat物件集合,並由springmvc的註解@ResponseBody將java物件轉換為json串,最終返回給js,EasyUI解析並顯示樹形結構。
開發步驟
EasyUI.tree樹為非同步載入,點開樹枝,才顯示下級節點。將傳遞引數,父節點的id,預設第一次頁面傳值為0。
第一步:在item-add.jsp頁面中呼叫js事件。
<tr>
<td>商品類目:</td>
<td>
<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>
<input type="hidden" name="cid" style="width: 280px;"></input>
</td>
</tr>
在a標籤上的class屬性中,綁定了easyui的按鈕,設定class名稱為selectItemCat,在js中將利用這個class來繫結onclick事件。隱藏域用來返回使用者選擇樹節點的值。
第二步:呼叫common.js中的initItemCat
……
initItemCat : function(data){
$(".selectItemCat").each(function(i,e){//i= index 下標,e:element:元素
var _ele = $(e);
if(data && data.cid){
_ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");
}else{
_ele.after("<span style='margin-left:10px;'></span>");
}
_ele.unbind('click').click(function(){
$("<div>").css({padding:"5px"}).html("<ul>")
.window({
width:'500',
height:"450",
modal:true,
closed:true,
iconCls:'icon-save',
title:'選擇分類',
onOpen : function(){ //當視窗開啟後執行
var _win = this; //this就指向當前的window
$("ul",_win).tree({
url:'/item/cat/list',
animate:true,
onClick : function(node){
//只有當是葉子節點時,才進行處理
if($(this).tree("isLeaf",node.target)){
// 填寫到cid中
//_ele.parent,在當前元素的父物件,目的縮小查詢範圍 _ele.parent().find("[name=cid]").val(node.id);
//find(“[name=cid]”)通過jQuery的選擇器,通過一個屬性進行選擇name=cid的
//元素後面,加上選擇節點的文字。
_ele.next().text(node.text).attr("cid",node.id);
$(_win).window('close');
if(data && data.fun){
data.fun.call(this,node);
}
}
}
});
},
onClose : function(){
$(this).window("destroy");
}
}).window('open');
});
});
},
……
第三步:pojo
建立ItemCat pojo繼承BasePojo;增加getText方法,為easy準備。
package com.jt.manage.pojo;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "tb_item_cat")
public class ItemCat extends BasePojo{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// 主鍵自增長策略
private Long id;
// 父類目ID=0時,代表的是一級的類目
@Column(name = "parent_id")
private Long parentId;
private String name;
// 狀態。可選值:1(正常),2(刪除)
private Integer status;
// 排列序號,表示同級類目的展現次序,如數值相等則按名稱次序排列。取值範圍:大於零的整數
@Column(name = "sort_order")
private Integer sortOrder;
// 該類目是否為父類目,1為true,0為false
@Column(name = "is_parent")
private Boolean isParent;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getSortOrder() {
return sortOrder;
}
public void setSortOrder(Integer sortOrder) {
this.sortOrder = sortOrder;
}
public Boolean getIsParent() {
return isParent;
}
public void setIsParent(Boolean isParent) {
this.isParent = isParent;
}
// 擴充套件get方法,滿足EasyUI的tree格式
public String getText() {
return getName();
}
public String getState() {
return getIsParent() ? "closed" : "open";
}
第四步:controller層
package com.jt.manage.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jt.manage.pojo.ItemCat;
import com.jt.manage.service.ItemCatService;
/**
* 商品類目相關的業務邏輯處理
*
*/
@RequestMapping("/item/cat")
@Controller
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
@RequestMapping("list")
@ResponseBody
public List<ItemCat> queryList(@RequestParam(value="id", defaultValue="0") Long id){
return this.itemCatService.queryListById(id);
}
}
第五步:service層
package com.jt.manage.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jt.manage.mapper.ItemCatMapper;
import com.jt.manage.pojo.ItemCat;
@Service
public class ItemCatService extends BaseService<ItemCat> {
@Autowired
private ItemCatMapper itemCatMapper;
public List<ItemCat> queryListById(Long id) {
return this.itemCatMapper.queryListById(id);
}
}
第六步:interface介面
package com.jt.manage.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.jt.manage.mapper.base.mapper.SysMapper;
import com.jt.manage.pojo.ItemCat;
public interface ItemCatMapper extends SysMapper<ItemCat>{
/**
* 根據ID查詢商品分類資料,parentId = id(引數)
*
* @param id
* @return
*/
List<ItemCat> queryListById(@Param("id") Long id);
}
第七步:mapper對映檔案
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.manage.mapper.ItemCatMapper">
<select id="queryItemCat" parameterType="long" resultType="ItemCat">
SELECT * FROM tb_item_cat WHERE STATUS=1 AND parent_id=#{id}
ORDER BY parent_id,sort_order
</select>
</mapper>
彈出視窗的呼叫過程
常見問題
trycatch能否寫在service層?
service層受spring的事務保護,如果在service層進行trycatch將破壞spring的回滾機制,造成無法回滾。因為spring看到有try,認定客戶要自己處理,所以不再執行回滾操作。因此需要try時,應該寫在controller層。
將json轉換List<ItemCat>時報錯
錯誤資訊:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "state" (class com.jt.manage.pojo.ItemCat), not marked as ignorable (8 known properties: "sortOrder", "status", "isParent", "parentId", "created", "updated", "name", "id"])
at [Source: N/A; line: -1, column: -1] (through reference chain: java.util.ArrayList[0]->com.jt.manage.pojo.ItemCat["state"])