基於AdminLTE的開發框架-AdminEAP
最近在研究使用AdminLTE框架化,本文講解使用sitemesh3使AdminLTE框架化的過程。系統架構為:SpringMVC+Spring+Hibernate+Maven+FreeMarker+Sitemesh
上圖為AdminEAP首頁展示目前所包含的系統功能,包含了元件整合、CURD增刪改查demo、系統工具、工作流、系統許可權與安全、Github原始碼與License、聯絡我們,提供了前端、後端整體解決方案,使得web開發更簡單。
使用者列表:
使用者編輯:
字典管理:
圖示選擇器:
回到正題,下面詳細講解sitemesh3在這個專案上的使用:(sitemesh3的配置可參考本人上篇部落格)
1、Maven中引入Sitemesh3
<dependency>
<groupId>org.sitemesh</groupId>
<artifactId>sitemesh</artifactId>
<version>3.0.0</version>
</dependency>
2、web.xml中配置sitemesh3過濾器
<filter> <filter-name>sitemesh</filter-name> <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class> </filter> <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3、在web.xml的同級目錄配置sitemesh3.xml
<?xml version="1.0" encoding="UTF-8"?> <sitemesh> <mapping path="/*" decorator="/decorator"></mapping> <mapping path="/*/*edit" exclue="true"></mapping> <!-- <mapping path="/*/*addUpdate" exclue="true"></mapping> <mapping path="/*/*add" exclue="true"></mapping> <mapping path="/*/*update" exclue="true"></mapping> --> <mapping path="/resources/*" exclue="true" /> <mapping path="/*/nodecorator/*" exclue="true"/> <mapping path="/nodecorator/*" exclue="true"/> <!-- 自定義 tag 規則 --> <!-- Sitemesh 3 預設只提供了 body,title,head 等 tag 型別,我們可以通過實現 TagRuleBundle 擴充套件自定義的 tag 規則: --> <content-processor> <tag-rule-bundle class="com.cnpc.framework.tags.CSSTagRuleBundle" /> <tag-rule-bundle class="com.cnpc.framework.tags.ScriptTagRuleBundle" /> </content-processor> </sitemesh>
上面定義了兩個自定義標籤,主要是將子頁面的樣式和指令碼渲染到裝飾頁面
CSSTagRuleBundle.java
package com.cnpc.framework.tags;
import org.sitemesh.SiteMeshContext;
import org.sitemesh.content.ContentProperty;
import org.sitemesh.content.tagrules.TagRuleBundle;
import org.sitemesh.content.tagrules.html.ExportTagToContentRule;
import org.sitemesh.tagprocessor.State;
public class CSSTagRuleBundle implements TagRuleBundle {
@Override
public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
defaultState.addRule("myCSS", new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("myCSS"), false));
}
@Override
public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
// TODO Auto-generated method stub
}
}
ScriptTagRuleBundle.java
package com.cnpc.framework.tags;
import org.sitemesh.SiteMeshContext;
import org.sitemesh.content.ContentProperty;
import org.sitemesh.content.tagrules.TagRuleBundle;
import org.sitemesh.content.tagrules.html.ExportTagToContentRule;
import org.sitemesh.tagprocessor.State;
public class ScriptTagRuleBundle implements TagRuleBundle {
@Override
public void install(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
defaultState.addRule("myScript", new ExportTagToContentRule(siteMeshContext, contentProperty.getChild("myScript"), false));
}
@Override
public void cleanUp(State defaultState, ContentProperty contentProperty, SiteMeshContext siteMeshContext) {
// TODO Auto-generated method stub
}
}
4、其中/decorator跳轉的路徑
@RequestMapping(method = RequestMethod.GET, value = "/decorator")
public String decorator(HttpServletRequest request) {
return "decorator";
}
decorator.html即為“母版頁”,其程式碼如下,請主要下面<sitemesh:write 部分
5、一個“子頁面”的配置,如使用者管理列表介面 user_list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>使用者列表</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.6 -->
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<myCSS>
<link rel="stylesheet" href="${basePath}/resources/adminlte/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet" href="${basePath}/resources/adminlte/plugins/datatables/select.bootstrap.min.css">
<link rel="stylesheet" href="${basePath}/resources/adminlte/plugins/bootstrap-validator/dist/css/bootstrap-validator.css"/>
<link rel="stylesheet" href="${basePath}/resources/adminlte/plugins/iCheck/all.css">
<link rel="stylesheet" href="${basePath}/resources/adminlte/plugins/datepicker/datepicker3.css">
</myCSS>
</head>
<body class="hold-transition skin-blue sidebar-mini">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
使用者管理 <small>列表</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> 首頁</a></li>
<li><a href="#">系統管理</a></li>
<li class="active">使用者管理</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<!-- /.box-header -->
<div class="dataTables_filter" id="searchDiv">
<input placeholder="請輸入姓名" name="name" class="form-control" type="search" likeOption="true" /> <input
placeholder="請輸入登入名" name="loginName" class="form-control" type="search" likeOption="true" />
<div class="btn-group">
<button type="button" class="btn btn-primary" action_type="search">查詢</button>
<button type="button" class="btn btn-default" action_type="reset">重置</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-default" action_type="add">新增</button>
<button type="button" class="btn btn-default" action_type="edit" >編輯</button>
<button type="button" class="btn btn-default" action_type="delete">刪除</button>
</div>
</div>
<div class="box-body">
<table id="user_table" class="table table-bordered table-striped table-hover">
</table>
</div>
<!-- /.box-body -->
</div>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
<myScript>
<script src="${basePath}/resources/adminlte/plugins/datatables/jquery.dataTables.js"></script>
<script src="${basePath}/resources/adminlte/plugins/datatables/dataTables.bootstrap.min.js"></script>
<script src="${basePath}/resources/common/js/dataTables.js"></script>
<!-- form -->
<script src="${basePath}/resources/adminlte/plugins/bootstrap-validator/dist/js/bootstrap-validator.js"></script>
<script src="${basePath}/resources/adminlte/plugins/iCheck/icheck.min.js"></script>
<script src="${basePath}/resources/adminlte/plugins/datepicker/bootstrap-datepicker.js"></script>
<script>
//tableId,queryId,conditionContainer
var userTable;
var winId="userWin";
$(function() {
//init table and fill data
userTable = new CommonTable("user_table", "user_list", "searchDiv");
//button event
$('button[action_type]').click(function() {
var action = $(this).attr('action_type');
var rowId=userTable.getSelectedRowId();
switch (action) {
case 'add':
modals.openWin({
winId:winId,
title:'新增使用者',
top:'auto',
width:'900px',
url:basePath+"/user/edit"
/*, hideFunc:function(){
modals.info("hide me");
},
showFunc:function(){
modals.info("show me");
} */
});
break;
case 'edit':
if(!rowId){
modals.info('請選擇要編輯的行');
return false;
}
modals.openWin({
winId:winId,
title:'編輯使用者【'+userTable.getSelectedRowData().name+'】',
top:'auto',
width:'900px',
url:basePath+"/user/edit?id="+rowId
});
break;
case 'delete':
if(!rowId){
modals.info('請選擇要刪除的行');
return false;
}
modals.confirm("是否要刪除該行資料?",function(){
ajaxPost(basePath+"/user/delete/"+rowId,null,function(data){
if(data.success){
//modals.correct("已刪除該資料");
userTable.reloadRowData();
}
});
})
break;
}
});
//form_init();
})
</script>
</myScript>
</body>
</html>
以上過程完成了AdminLTE的框架化,但是存在一個性能問題,即每次需要訪問/decorator路徑,會重置頂部導航和左側選單,導致不能記住頂部導航和左側當前選單。後續可能不會使用Sitemesh3,可能會用jquery 的load方法。
當然有人說,sitemesh3太折騰了,用iframe不就可以嗎?確實可以,但iframe的高度自適應的問題是在太噁心了,也存在一些其他問題。