http://blog.csdn.net/yerenyuan_pku/article/details/72845954
上文我們一起學習了內容分類管理,雖說實現了展示內容分類和新增節點這兩個功能,但重命名節點和刪除節點這兩個功能還未開發,主要是時間太緊了,以后我一定會完善這些功能,讀者如果有興趣,也可以實現這些功能,希望大家都能學有所成。廢話扯了一大堆,進入主題,本文我們將一起學習內容管理。
內容列表查詢
首先,我們先來看看內容管理后台頁面,如下圖所示,可以看到頁面分為兩部分,即分為左側內容分類和右側內容列表兩個部分。
為什么內容管理頁面左側的內容分類樹形列表直接就是好的呢?其實我們看看代碼就知道了,我們訪問的入口是index.jsp頁面,這個頁面有”內容管理”模塊,當我們點擊內容管理時,就會去請求content.jsp頁面。
我們再來看看content.jsp頁面的代碼,如下圖所示。可以看到上面那個div就是展示我們的內容分類列表的,發起的請求與我們上文中為實現展示內容分類功能發起的請求完全一樣,因此這里不用我們做任何處理就已經可以使用了。下面的div就是內容管理后台頁面的右部分,用來顯示內容列表,頁面加載的時候,會發起url:'/content/query/list',queryParams:{categoryId:0}
這樣的請求,這個請求會去查詢所有內容分類下的所有內容。內容列表的展示其實跟商品列表的展示及其相似,大家可以參考我之前的淘淘商城系列——MyBatis分頁插件(PageHelper)的使用以及商品列表展示這篇文章進行學習,不同的地方是內容列表要根據左邊樹形節點的id的變化而變化。
那么內容列表又是如何跟左邊的內容分類聯系起來的呢?我們看下面的js代碼,如下圖所示。
$(function(){...});
函數是在頁面加載完之后觸發執行的js代碼。var tree = $("#contentCategoryTree");
顯然是獲取內容分類樹。var datagrid = $("#contentList");
是獲取內容列表。onClick : function(node){...}
這段代碼的意思是當我們點擊左邊內容分類樹的某個節點時,會做一下判斷,判斷是不是葉子節點,如果是葉子節點那么就給categoryId賦值為這個葉子節點的id並且會重新加載內容列表,也就意味着重新發起url:'/content/query/list'
請求,只是這時的queryParams參數中categoryId的值變成了單個葉子節點的id。
搞清了內容列表的展示原理后,照理說我們現在就應該馬上實現內容列表展示的功能,但因為時間太緊,不打算實現該功能,留待以后開發。
未完,待續。。。
新增內容
我們還得從頁面代碼說起,新增內容是在content.jsp頁面當中定義的,我們可以看到內容列表中有”toolbar:contentListToolbar”這么一句代碼,這句代碼的意思是定義了工具欄,工具欄中有多個功能。
我們來看看工具欄的代碼,里面有新增、編輯、刪除三個操作,如下所示:
var contentListToolbar = [{ text:'新增', iconCls:'icon-add', handler:function(){ var node = $("#contentCategoryTree").tree("getSelected"); if(!node || !$("#contentCategoryTree").tree("isLeaf",node.target)){ $.messager.alert('提示','新增內容必須選擇一個內容分類!'); return ; } TT.createWindow({ url : "/content-add" }); } },{ text:'編輯', iconCls:'icon-edit', handler:function(){ var ids = TT.getSelectionsIds("#contentList"); if(ids.length == 0){ $.messager.alert('提示','必須選擇一個內容才能編輯!'); return ; } if(ids.indexOf(',') > 0){ $.messager.alert('提示','只能選擇一個內容!'); return ; } TT.createWindow({ url : "/content-edit", onLoad : function(){ var data = $("#contentList").datagrid("getSelections")[0]; $("#contentEditForm").form("load",data); // 實現圖片 if(data.pic){ $("#contentEditForm [name=pic]").after("<a href='"+data.pic+"' target='_blank'><img src='"+data.pic+"' width='80' height='50'/></a>"); } if(data.pic2){ $("#contentEditForm [name=pic2]").after("<a href='"+data.pic2+"' target='_blank'><img src='"+data.pic2+"' width='80' height='50'/></a>"); } contentEditEditor.html(data.content); } }); } },{ text:'刪除', iconCls:'icon-cancel', handler:function(){ var ids = TT.getSelectionsIds("#contentList"); if(ids.length == 0){ $.messager.alert('提示','未選中商品!'); return ; } $.messager.confirm('確認','確定刪除ID為 '+ids+' 的內容嗎?',function(r){ if (r){ var params = {"ids":ids}; $.post("/content/delete",params, function(data){ if(data.status == 200){ $.messager.alert('提示','刪除內容成功!',undefined,function(){ $("#contentList").datagrid("reload"); }); } }); } }); } }];
我對新增操作作如下講解:
- text指定我們看到的圖標后面的文字。
- iconCls指定新增圖標。
handler:function()
是當我們點擊”新增”按鈕時觸發的函數。var node = $("#contentCategoryTree").tree("getSelected");
的意思是得到用戶選中的內容分類節點。if(!node || !$("#contentCategoryTree").tree("isLeaf",node.target)){
的意思是如果選中的不是節點或者該節點不是葉子節點,那么這時就彈出一個”新增內容必須選擇一個內容分類!”的提示框。如果點擊的是葉子節點的話,會調用common.js文件當中定義的TT的createWindow方法初始化一個彈出框,彈出框中顯示的頁面是由參數url: “/content-add”指定的,也就是content-add.jsp頁面。
下面我們便來看下content-add.jsp頁面,表格中的字段名稱與我們的數據庫中表的字段是一致的,這樣我們便可以直接使用逆向工程生成的代碼了。
當以上頁面加載完之后,會觸發$(function(){...}
方法,下面我來詳細分析一下該方法中的代碼。
contentAddEditor = TT.createEditor("#contentAddForm [name=content]");
的意思是初始化一個富文本編輯器。TT.initOnePicUpload();
的意思是初始化單張圖片上傳按鈕,也就是說一次只能選擇一張圖片(因為我們的pic和pic2字段各自對應一張圖片路徑)。$("#contentAddForm [name=categoryId]").val($("#contentCategoryTree").tree("getSelected").id);
這行代碼的意思是把用戶選擇的內容分類節點的id賦值給隱藏域<input type="hidden" name="categoryId"/>
,這樣我們在提交表單的時候便把內容分類id也一並提交了。
當我們點擊提交超鏈接提交表單的時候,就會觸發submitForm : function ()
方法,下面我也來詳細分析一下該方法中的代碼。
if(!$('#contentAddForm').form('validate')){
的意思是如果表單輸入不合法,那么會提示”表單還未填寫完!”。contentAddEditor.sync();
的意思是如果表單填寫合法,那么富文本編輯器將與表單中的隱藏域字段(<textarea>
字段)進行內容同步。$.post("/content/save")
的意思是發起url為/content/save的請求。$("#contentAddForm").serialize()
將表單中的數據序列化為key-value形式的字符串。function(data){...}
指回調函數,if(data.status == 200){
的意思是如果返回的狀態為200的話說明內容添加成功了,$("#contentList").datagrid("reload");
意思是內容添加成功后,內容列表要進行重新加載。TT.closeCurrentWindow();
的意思是關閉彈出窗口。
當我們點擊重置超鏈接重置表單時,就會觸發clearForm : function()
方法。$('#contentAddForm').form('reset');
的意思是將剛才表單中輸入的內容清空。
分析了以上js代碼,下面我們來實現添加內容這個功能。首先我們來編寫Service層的代碼。在taotao-content-interface工程下的com.taotao.content.service包中新建一個接口——ContentService.java,並在接口中添加一個insertContent方法,如下圖所示。
接着我們來實現上面的接口,我們在taotao-content-service工程的com.taotao.content.service.impl包下新建一個ContentServiceImpl實現類,該類實現ContentService接口,如下圖所示。
為方便大家復制,將該實現類代碼貼出,如下:
/** * 內容管理Service * <p>Title: ContentServiceImpl</p> * <p>Description: </p> * <p>Company: www.itcast.cn</p> * @version 1.0 */ Service public class ContentServiceImpl implements ContentService { @Autowired private TbContentMapper contentMapper; @Override public TaotaoResult insertContent(TbContent content) { // 補全pojo的屬性 content.setCreated(new Date()); content.setUpdated(new Date()); // 向內容表中插入數據 contentMapper.insert(content); return TaotaoResult.ok(); } }
- 1
- 2
下面我們發布一下該服務的這個接口,我們在taotao-content-service工程的spring目錄下的applicationContext-service.xml配置文件中添加如下配置:
<dubbo:service interface="com.taotao.content.service.ContentService" ref="contentServiceImpl" timeout="300000" />
然后我們再來編寫表現層的代碼。首先我們需要在taotao-manager-web工程的springmvc.xml配置文件中添加對ContentService的引用,即要向springmvc.xml配置文件中添加如下配置:
<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
接着我們需要在taotao-manager-web工程中添加ContentController類來實現新增內容這個功能。其中@RequestMapping("/content/save")
注解中的url是從content-add.jsp頁面當中粘貼過來的。
在啟動測試之前,我們需要先打包taotao-content到本地maven倉庫。由於新增內容這個功能涉及到了taotao-manager和taotao-content這兩個服務和taotao-manager-web,所以我們依次啟動taotao-manager和taotao-content,然后是taotao-manager-web,啟動成功之后,然后去添加一個內容,添加界面如下圖所示。
點擊”提交”之后,我們可以發現tb_content表中便有了我們剛才添加的內容,如下圖所示。
編輯內容
由於時間緊張,在此並不實現該功能,留待以后開發。未完,待續。。。敬請期待。
刪除內容
由於時間緊張,在此並不實現該功能,留待以后開發。未完,待續。。。敬請期待。