1. 程式人生 > >基於AdminLTE的開發框架-AdminEAP

基於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的高度自適應的問題是在太噁心了,也存在一些其他問題。