当前位置: 首页 > 知识库问答 >
问题:

thymeleaf th: inline="javascript"问题

姜学海
2023-03-14

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

最后一段javascript代码应该添加到$(文档)中。就绪{}我的html页面的一部分。

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

如果我使用inline=“text”in,则不会引用,而是转义所有引号;-)-也不错,但无法使用8)

如果我尝试使用inline=“none”则什么也不会发生。

下面是一些例子

MyModelGetter创建了以下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处理它的方式)。

所以如果我尝试内联="text"

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

这逃脱了引用。

inline="无"我真的不明白,因为它什么也不做

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

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

非常感谢,约翰,干杯

共有2个答案

裴劲
2023-03-14

使用${pageHelper.documentReady}代替${pageHelper.documentReady}

温镜
2023-03-14

我会改变方法。

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

当然,我让模板决定加载什么。如果您正在显示一个图库,则按照您的意愿渲染它,并使用数据属性定义与某些JS代码相关的图库。然后为自己编写一个好的jQuery插件来处理您的库。

一个相对基本的例子:

默认布局装饰器:布局/默认。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:fragmentdiv。我们将使用这个布局div来包含库所需的jQuery插件。

包含常规脚本的文件:片段/脚本。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个片段,它们包含在decorator中。在header片段中,为JS层提供了一个有用的上下文路径,以及一个defaultTheme,只是为了它。然后从我们的模型中定义并指定一个库对象。页脚片段加载jQuery库和一个主站点JS文件,同样用于本例。

包含惰性加载库的页面:产品。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标签中的标题和一个带有数据库属性的空div。这个属性是我们将在jQuery插件中用来初始化库的。

该值被设置为lazyload,所以我们的插件知道我们需要在某个变量集中找到图像ID。如果我们的插件支持的唯一东西是一个懒惰加载的库,这很容易是空的。

因此,布局加载一些默认脚本,通过巧妙地放置layout:fragments,您允许站点的某些部分独立于其他部分加载库。

下面是一个基本的Spring控制器示例,用于我们的应用程序: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插件,初始化库所需的一切都应该加载并准备就绪。

这不是一个完美的例子,但我认为这是一个非常直接的web应用程序设计模式。

 类似资料:
  • 这是为什么?

  • 使用上述代码在浏览器中新建一个IndexedDB数据库,再使用下面的代码删除数据库,发现删除没反应,一直没有输出删除成功,请问这是为什么?

  • 我有一个vue写的标签 其中,queryByPrimaryKey返回的是一个promise,所以这里用await等待promise的值,因为用到了await,所以外层又需要用async包裹,这样整体函数返回的又是一个promise,那么src属性实际上要的是返回的string值,而不是包裹着string的promise,我如何拿到string值?

  • 在我前面的问题中:确保javascript游戏计时 ... 很明显,Javascript/Canvas游戏中的客户端计时是不安全的。我知道关于不信任客户的咒语——这就是导致我首先挣扎的原因。:-) 所以,如果我真的把所有的时间都转移到服务器上并处理它,这是一个后续问题。游戏显然需要在提交之前完成。由于游戏谜题都是Javascript,这就引入了操纵客户端代码来伪造游戏完成的问题。 我已经在一个单独

  • 请问上面这段代码,我想封装成Promise 这种 直接调用this.home_barlist1().then 该怎么改呢? 我改成下面这样 好像不行

  • 我想匹配一段字符串中所有的input 并使用replace进行替换,如果input里面有类似data-* 这种自定义属性的就跳过 不知道这种正则该怎么写,我也阅读了文档并使用google。都没找到 比如 <input type='text' /> 这种Input就匹配,<input data-xxx /> 带有自定义属性的input 正则则不匹配

  • 问题内容: 我有以下代码片段。 上面的代码用于生成5个链接,并将每个链接与警报事件绑定以显示当前链接ID。但这是行不通的。当您单击生成的链接时,它们都说“链接5”。 但是以下代码段符合我们的预期。 这里引用了以上两个片段。 但是它是如何工作的以及 关闭 是如何工作的,这些都是我无法理解的。为什么第一个不起作用而第二个却起作用?任何人都可以对魔术进行详细说明吗? 谢谢。 问题答案: 解释第一个示例:

  • 定义一个枚举,将其中一个取值作为replace方法的第二个参数,这时候会报错,该怎么处理?