web 实验-抽取公共页面
# 340.web 实验-抽取公共页面
继续完善我们的后台管理系统
# 需求
登录后,首页左侧有很多菜单,此时点进去都是不能正常跳转的;
我们完善 Data Table 下所有功能,使其能正常跳转:
# 新建文件夹
由于功能很多,全部页面放在一个文件夹不太方便,因此新建一个 src/main/resources/templates/table 文件夹,存放表格相关的页面。
然后我们将《前端资源文件 demo》目录下这几个文件,放到 table 文件夹:
- basic_table.html
- responsive_table.html
- dynamic_table.html
- editable_table.html
- pricing_table.html
# 新建表格处理的 Controller
新增一个 Controller,用来返回 table 下的页面:
package com.peterjxl.learnspringbootwebadmin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class TableController {
@GetMapping("/basic_table")
public String basic_table(){
return "table/basic_table";
}
@GetMapping("/dynamic_table")
public String dynamic_table(){
return "table/dynamic_table";
}
@GetMapping("/responsive_table")
public String responsive_table(){
return "table/responsive_table";
}
@GetMapping("/editable_table")
public String editable_table(){
return "table/editable_table";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
然后我们访问相关链接,是能正常访问的:
# 重复代码分析
我们首页,跳转到表格功能的页面,是访问的 HTML:
<li><a href="basic_table.html"> Basic Table</a></li>
<li><a href="dynamic_table.html"> Advanced Table</a></li>
<li><a href="responsive_table.html"> Responsive Table</a></li>
<li><a href="editable_table.html"> Edit Table</a></li>
2
3
4
除了首页,表格功能部分的页面,也有左侧的菜单栏,其也是通过 HTML 的方式访问的,要改的话不太方便;
考虑到左侧菜单页,以及顶部的菜单栏是公共的,可以抽取;只有内容区域不一样。
首先,打开 main.html,head 标签里主要是引入了一些 CSS,然后左侧菜单栏的相关代码大概有 100 多行(注释也很清晰);然后紧接着是内容区的代码;再下面则是引入了一些 JS。
ps:菜单顶部的代码,其实是在内容区的代码中
其他页面同理(例如 basic_table.html),大概也是这样的结构。(也就是 CSS 和 JS 的引入,也有公共的部分)
# 抽取公共页面
新建 resources/templates/common.html,用来放公共的内容。首先是 CSS 和 JS 的引入:
<!DOCTYPE html>
<html lang="en">
<head>
<!--common-->
<link href="css/style.css" rel="stylesheet">
<link href="css/style-responsive.css" rel="stylesheet">
</head>
<body>
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/jquery-ui-1.9.2.custom.min.js"></script>
<script src="js/jquery-migrate-1.2.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/modernizr.min.js"></script>
<script src="js/jquery.nicescroll.js"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
然后我们改为 Thymeleaf 的取值方式:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link href="css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
<link href="css/style-responsive.css" th:href="@{/css/style-responsive.css}" rel="stylesheet">
<script src="js/html5shiv.js" th:src="@{/js/html5shiv.js}"></script>
<script src="js/respond.min.js" th:src="@{/js/respond.min.js}"></script>
</head>
<body>
<script th:src="@{js/jquery-1.10.2.min.js}"></script>
<script th:src="@{js/jquery-ui-1.9.2.custom.min.js}"></script>
<script th:src="@{js/jquery-migrate-1.2.1.min.js}"></script>
<script th:src="@{js/bootstrap.min.js}"></script>
<script th:src="@{js/modernizr.min.js}"></script>
<script th:src="@{js/jquery.nicescroll.js}"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
然后就是 copy 一份 main 页面中,左侧菜单栏和顶部菜单的代码,放到 common.html 了;由于代码很多,这里就不 copy 了。
接下来我们看看 Thymeleaf 的 官网文档 (opens new window),是如何说明抽取的:
简单来说,就是定义一个标签,里面用上 th:fragment
;然后要在引入的页面中,使用 th:insert
。
除此之外,也可以不声明 th:fragment
,而是直接使用 CSS 选择器,直接引入某个页面的标签:
根据文档,修改 common.html 如下:添加 id
或 th:fragment
属性
# 替换
声明了公共页面后,下一步就是替换了,根据 官网文档 (opens new window),主要是通过 th:insert
, th:replace
和 th:include
属性,然后属性值则写某个页面的名字(不用前缀和后缀)。假设公告部分是这样:
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
2
3
然后其他页面这样引入:
<div th:insert="~{footer :: copy}"></div>
<div th:replace="~{footer :: copy}"></div>
<div th:include="footer :: copy"></div>
2
3
4
5
渲染的结果:
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
2
3
4
5
6
7
8
9
10
11
12
13
14
其实根据名字,应该也能猜出来,这里就不赘述了。注意,th:include
虽然不推荐使用,但这里为了方便演示,还是用了下。
# 替换 CSS
接下来我们替换 main 页面,将 main 页面的如下内容:
<!--common-->
<link href="css/style.css" rel="stylesheet">
<link href="css/style-responsive.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
2
3
4
5
6
7
8
9
10
11
12
替换为如下内容:
<link th:include="common :: commonheader">
然后我们重启,重新登录,可以看到能正常显示,这就说明替换成功了;而且打开控制台,也能看到有代码:
也能看到有请求 style.css:
如果使用 th:replace
属性,则会有两个 head 标签,只不过浏览器能帮我们修正这种情况:
# 替换 JS
同理,将 main 页面的如下内容:
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/jquery-ui-1.9.2.custom.min.js"></script>
<script src="js/jquery-migrate-1.2.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/modernizr.min.js"></script>
<script src="js/jquery.nicescroll.js"></script>
2
3
4
5
6
替换为:
<div th:replace="common :: #commonscript"></div>
查看源代码,也能看到:
# 替换菜单栏和顶部菜单
<div th:replace="common :: #leftmenu"></div>
<div th:replace="common :: headermenu"></div>
2
3
# 修改超链接
我们修改 common 页面中,关于表格功能的超链接,
<li class="menu-list"><a href="#"><i class="fa fa-th-list"></i> <span>Data Tables</span></a>
<ul class="sub-menu-list">
<li><a th:href="@{basic_table}"> Basic Table</a></li>
<li><a th:href="@{dynamic_table}"> Advanced Table</a></li>
<li><a th:href="@{responsive_table}"> Responsive Table</a></li>
<li><a th:href="@{editable_table}"> Edit Table</a></li>
</ul>
</li>
2
3
4
5
6
7
8
# 其他页面
同理,将 table 相关的页面也替换菜单和顶部、CSS 和 JS 的引入部分
# 源码
已将本文源码上传到 Gitee (opens new window) 或 GitHub (opens new window) 的分支 demo2,读者可以通过切换分支来查看本文的示例代码