关键词搜索

源码搜索 ×
×

spring boot + thymeleaf下的模块化编程

发布2020-05-25浏览1026次

详情内容

题目也不知道是否准确。

thymeleaf只是一种前端模板引擎。spring boot与之结合,可以部分实现前后端分离。为什么说部分实现呢,因为所谓模板也者,上面会放置一些服务器端的输出信息,还是要靠服务器解析,完了之后再输出到前端的浏览器。完全的前后端分离,据说是服务器信息都来自于ajax的请求。但是我觉得这是一种扯淡。浏览器本身的功能非常弱,其定位就是用于展示和收集和提供给用户的一些交互,你让它去解析、管理一些资源,实在勉为其难。所以,想做到这种服务器端和浏览器端决然分开,只通过ajax这么一条狭窄的管道或者脐带进行联系,以方便所谓后端、前端的工人们各行其是各自嗨,我认为是一种误解。

所以前端的定义,不应该这么狭窄,只包括浏览器。我觉得控制器也应该包含在前端的范围里。只有model、service这类,才算后端。当然啦,可能前端有一些JS框架,可以进行所谓的一些什么双向绑定,无形中就让你施施然进行一些数据的呈现。但这些做法,一定很不好理解,一定很多语法限制,简直反人类。当然啦,我也是没有接触过这些框架才这么说,也许真的是极好的。

扯远了。激动了。excuse me。

前面说到,thymeleaf只是一种前端模板引擎。模板引擎有许多,thymeleaf只是其中一种,spring boot可以跟许多模板引擎结合,不一定非是thymeleaf。按理说,thymeleaf本身是百衲衣的思想,将一个完整的视图,可以拆成多个片段,以利于复用,或高内聚啥的。一个函数如果成百上千行,阅读起来一定很痛苦,分成几个小函数就好多了。thymeleaf也有这么个好处。

这样就引出一个问题:thymeleaf的片段,如果包含了服务器端的信息,那么这些信息来源于哪里?

具体一点说,视图上的服务器端信息(也可以叫动态信息)基本来源于控制器,现在一个视图分成了多个片段,如果片段上要使用服务器端信息,那么这些信息来源于哪里?是视图对应的控制器,还是片段的控制器?thymeleaf的片段,基本上是静态内容,引用方式也由视图自行include,片段并没有对应的控制器。但如果这样的话,服务器端内容全部挤在一个控制器,然后视图却分作不同的片段,这就感觉很割裂。真是一个问题。

对于thymeleaf片段,如果需要使用服务器端的动态内容,我总结了一下,认为可以有3种途径实现:

1、片段没有控制器,由视图控制器产生,或者视图产生,通过参数传递方式传给片段

视图spot/shares/slider::top,传递一个动态变量docks给片段。动态变量docks在视图中构造,但更多情况下,是控制器中输出。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <th:block th:include="shares/default::head" />
    <th:block th:include="spot/shares/slider::index" />
</head>
<body>
    <th:block th:with="docks=${
        {
            {'res','资源目录','res'},
            {'search','图斑查找','search'},
            {'list','结果列表','list'}
        }
    }">
        <th:block th:include="spot/shares/slider::top(${docks},'res')" />
    </th:block>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

片段spot/shares/slider::top

<block th:fragment="top(docks,curmenu)" >
    <div class="sl-top normal-box sl-box-top">
        <div class="sl-menu normal-box">
           <!--/* 使用动态变量docks */-->
            <th:block th:each="d:${docks}">
                <div th:class="${curmenu eq d[0]} ? 'btn active' : 'btn'" th:title="${d[1]}" th:url="${d[2]}" th:name="${d[0]}">
                    <span th:class="'bk-icon btn-icon btn-' + ${d[0]}"></span>
                </div>
            </th:block>
        </div>
    </div>
   
</block>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2、片段通过ajax请求服务器端,获得数据

无须举例

3、片段配备控制器/action,视图通过servletContext.getRequestDispatcher的方式引用片段

1)视图

<div style="padding: 0 10px;">
    <th:block th:utext="${#servletContext.getRequestDispatcher('/bench/jsjc/new').include(#request,#response)}"/>
</div>
  • 1
  • 2
  • 3

2)片段/bench/jsjc/new,动态变量projectList来自于控制器

<div class="list-cont-area" th:each="item2:${projectList}">
    <div class="list-cont-block" style="">
        <div>
            <span th:text="${#dates.format(item2.satAdmeasuredate, 'yyyy-MM-dd HH:mm:ss')}"></span>
        </div>
    </div>
    <div class="button-block" style="" th:text="${item2.proGrantdepartmentLevel}"></div>
</div>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3)片段对应的控制器

@Controller("benchJsjcControllern")
@RequestMapping(value = {"/bench/jsjc"})
public class JsjcControllern extends BaseController {
    @RequestMapping(value = {"/new"})
    public String jsjcNew(Model model) {
        List<ViewProjectCertif> projectList = getNewSeaProjects(1, 3, qhid);
        model.addAttribute("projectList", projectList);
        return "bench/frags/jsjc_new";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4、总结

倾向于使用方式一和二。毕竟thymeleaf的片段倾向于静态内容,很少有对应控制器的。但假如真的需要,也可以用第三种方式。毕竟对应自己的action,利于加强代码的内聚性。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载