spring - Thymeleaf th :inline ="javascript" issue

标签 spring thymeleaf

我不知道如何解决以下问题:我想让我的模型根据一些模型逻辑动态生成真正的 javascript。

这最后一段 javascript 代码应该添加到我的 html 页面的 $(document).ready { } 部分中。

问题是:如果我使用 inline="javascript",代码会被引用,因为我的 getter 是一个字符串(Thymeleaf 文档中就是这样提到的,但这不是我需要的 ;-)

如果我使用 inline="text"in 未引用但所有引号都被转义了 ;-) - 也不错但无法使用 8)

如果我尝试 inline="none"什么都不会发生。

这里是例子

我的模型 getter 创建了以下 Javascript 代码。

PageHelper 类

public String documentReady() {

// do some database operations to get the numbers 8,5,3,2
return "PhotoGallery.load(8,5,3,2).loadTheme(name='basic')";

}

所以如果我现在尝试 inline="javascript"

<script th:inline="javascript">
/*<![CDATA[*/
    jQuery().ready(function(){
        /*[[${pageHelper.documentReady}]]*/
    });
/*]]>*/
</script>

它将被渲染到

<script>
/*<![CDATA[*/
    jQuery().ready(function(){
        'PhotoGallery.load(8,5,3,2).loadTheme(name=\'basic\')'
    });
/*]]>*/
</script>

这没有帮助,因为它是一个字符串文字,仅此而已(这就是 Thymeleaf 处理它的方式)。

所以如果我尝试 inline="text" 而不是

<script>
/*<![CDATA[*/
    jQuery().ready(function(){
        PhotoGallery.load(8,5,3,2).loadTheme(name=&#39;basic&#39;)
    });
/*]]>*/
</script>

转义引号。

inline="none"我不太明白,因为它什么都不做

<script>
/*<![CDATA[*/
    jQuery().ready(function(){
        [[${pageHelper.documentReady}]]
    });
/*]]>*/
</script>

说实话,我不知道如何解决这个问题,希望任何人都知道如何处理这个问题。

非常感谢提前 干杯 约翰

最佳答案

我会改变方法。

Thymeleaf 允许您轻松地在模板中添加模型变量以在 Javascript 中使用。在我的实现中,我通常将这些变量放在结束 header 标记之前的某个位置;以确保它们在 JS 加载后就在页面上。

当然,我让模板决定究竟要加载什么。如果您正在显示一个图库,则按照您的方式呈现它并使用数据属性来定义与某些 JS 代码相关的图库。那就给自己写个不错的jQuery plugin处理您的画廊。

一个比较基础的例子:

默认布局装饰器:layout/default.html

<!doctype html>
<html xmlns:layout="http://www.thymeleaf.org" xmlns:th="http://www.thymeleaf.org">
<head>
  <title>My Example App</title>
  <object th:remove="tag" th:include="fragments/scripts :: header" />
</head>
<body>
  <div layout:fragment="content"></div>
  <div th:remove="tag" th:replace="fragments/scripts :: footer"></div>
  <div th:remove="tag" layout:fragment="footer-scripts"></div>
</body>
</html>

这里要注意的是包含了通用页脚脚本,然后定义了一个 layout:fragment div。我们将使用这个布局 div 来包含画廊所需的 jQuery 插件。

带有通用脚本的文件:fragments/scripts.html

<div th:fragment="header" xmlns:th="http://www.thymeleaf.org">
  <script type="text/javascript" th:inline="javascript">
    /*<![CDATA[*/
    var MY_APP = {
      contextPath: /*[[@{/}]]*/,
      defaultTheme: /*[[${theme == null} ? null : ${theme}]]*/,
      gallery: {
        theme: /*[[${gallery == null} ? null : ${gallery.theme}]]*/,
        images: /*[[${gallery == null} ? null : ${gallery.images}]]*/,
        names: /*[[${gallery == null} ? null : ${gallery.names}]]*/
      }
    };
    /*]]>*/
  </script>
</div>
<div th:fragment="footer" xmlns:th="http://www.thymeleaf.org">
  <script type="text/javascript" src="/js/jquery.js"></script>
  <script type="text/javascript" src="/js/my_app.js"></script>
</div>

在脚本文件中,有 2 个片段,它们是从装饰器中包含的。在标题片段中,为 JS 层包含了一个有用的上下文路径,以及一个 defaultTheme 只是为了它的 hell 。然后从我们的模型中定义和分配一个画廊对象。页脚片段加载 jQuery 库和主站点 JS 文件,同样用于本示例。

带有延迟加载图库的页面:products.html

<html layout:decorator="layout/default" xmlns:layout="http://www.thymeleaf.org/" xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Products Landing Page</title>
</head>
<body>
  <div layout:fragment="content">
    <h1>Products</h1>
    <div data-gallery="lazyload"></div>
  </div>
  <div th:remove="tag" layout:fragment="footer-scripts">
    <script type="text/javascript" src="/js/my_gallery.js"></script>
  </div>
</body>
</html>

我们的产品页面没有太多内容。使用默认装饰器,此页面会覆盖头部中的页面标题。我们的内容片段包括一个 h1 标签中的标题和一个带有 data-gallery 属性的空 div。我们将在 jQuery 插件中使用这个属性来初始化图库。

该值设置为lazyload,因此我们的插件知道我们需要在某个地方的某个变量集中找到图像ID。如果我们的插件唯一支持的是延迟加载的画廊,这很容易为空。

因此布局会加载一些默认脚本,并巧妙地放置 layout:fragments,您可以让网站的某些部分独立于其余部分加载库。

这是一个基本的 Spring Controller 示例,用于我们的应用程序:MyController.java

@Controller
public class MyController {
  @RequestMapping("/products")
  public String products(Model model) {        
    class Gallery {
      public String theme;
      public int[] images;
      public String[] names;
      public Gallery() {
        this.theme = "basic";
        this.images = new int[] {8,5,3,2};
        this.names = new String[] {"Hey", "\"there's\"", "foo", "bar"};
      }
    }
    model.addAttribute("gallery", new Gallery());
    return "products";
  }
}

Gallery 类被内嵌在 products 方法中,以简化我们这里的示例。这很容易成为某种类型的服务或存储库,它返回一组标识符,或者您需要的任何东西。

我们创建的 jQuery 插件可能看起来像这样:my_gallery.js

(function($) {
  var MyGallery = function(element) {
    this.$el = $(element);
    this.type = this.$el.data('gallery');
    if (this.type == 'lazyload') {
      this.initLazyLoadedGallery();
    }
  };

  MyGallery.prototype.initLazyLoadedGallery = function() {
    // do some gallery loading magic here
    // check the variables we loaded in our header
    if (MY_APP.gallery.images.length) {
      // we have images... sweet! let's fetch them and then do something cool.
      PhotoGallery.load(MY_APP.gallery.images).loadTheme({
        name: MY_APP.gallery.theme
      });
      // or if load() requires separate params
      var imgs = MY_APP.gallery.images;
      PhotoGallery.load(imgs[0],imgs[1],imgs[2],imgs[3]).loadTheme({
        name: MY_APP.gallery.theme
      });
    }
  };

  // the plugin definition
  $.fn.myGallery = function() {
    return this.each(function() {
      if (!$.data(this, 'myGallery')) {
        $.data(this, 'myGallery', new MyGallery(this));
      }
    });
  };

  // initialize our gallery on all elements that have that data-gallery attribute
  $('[data-gallery]').myGallery();
}(jQuery));

产品页面的最终呈现如下所示:

<!doctype html>
<html>
<head>
  <title>Products Landing Page</title>
  <script type="text/javascript">
    /*<![CDATA[*/
    var MY_APP = {
      contextPath: '/',
      defaultTheme: null,
      gallery: {
        theme: 'basic',
        images: [8,5,3,2],
        names: ['Hey','\"there\'s\"','foo','bar']
      }
    };
    /*]]>*/
  </script>
</head>
<body>
  <div>
    <h1>Products</h1>
    <div data-gallery="lazyload"></div>
  </div>
  <script type="text/javascript" src="/js/jquery.js"></script>
  <script type="text/javascript" src="/js/my_app.js"></script>
  <script type="text/javascript" src="/js/my_gallery.js"></script>
</body>
</html>

如您所见,Thymeleaf 在将您的模型转换为有效的 JS 方面做得非常好,并且实际上在需要的地方添加了引号并将它们转义。一旦页面完成渲染,文件末尾的 jQuery 插件,初始化画廊所需的一切都应该加载并准备就绪。

不是一个完美的例子,但我认为这是一个非常简单的网络应用程序设计模式。

关于spring - Thymeleaf th :inline ="javascript" issue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32596600/

相关文章:

spring - :field attributes in checkbox 的值

spring-mvc - 使用 HashMap 作为 Form Backing Bean Spring MVC + ThymeLeaf

spring - 混合 html 和 json 模板时如何在 thymeleaf 中正确设置内容类型

java - 在 spring 集成中将多个有效负载嵌入到 "Message"对象中的最佳方法是什么?

java - Spring Boot依赖bean未设置值

java - 拆分器返回空数组列表 Spring 集成

java - 如何分析hibernate JPA session 信息?

spring - jQuery mobile - 浏览器刷新页面后完全困惑

java - Thymeleaf 构造对象

java - 使用 JAVA 将 HTML5 编写的 SVG 转换为 JPG