Thymeleaf th:inline ="javascript"问题 [英] Thymeleaf th:inline="javascript" issue

查看:259
本文介绍了Thymeleaf th:inline ="javascript"问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I don't know how to solve the following: I'd like to let my Model generate real javascript dynamically based on some model logic.

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

This final piece of javascript code then should be added inside the $(document).ready { } part of my html page.

问题是:如果我使用inline ="javascript",则由于我的getter是一个字符串而引用了该代码(这是Thymeleaf文档中提到的方式,但这不是我所需要的;-)

The thing is: If I use inline="javascript", the code gets quoted as my getter is a String (that is how it is mentioned in the Thymeleaf doc but it's not what I need ;-)

如果我使用inline ="text"而不加引号,而是所有引号都转义;-)-也不错,但无法使用8)

If I use inline="text" in is not quoted but all quotes are escaped instead ;-) - also nice but unusable 8)

如果我尝试inline ="none",则不会发生任何事情.

If I try inline="none" nothing happens.

以下是示例

我的模型获取者创建了以下Javascript代码.

My model getter created the following Javascript code.

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"

So if I now try 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>

这没有帮助,因为它是String文字,仅此而已(这是Thymeleaf的处理方式).

Which doesn't help as it is a String literal, nothing more (this is how Thymeleaf deals with it).

因此,如果我改用 inline ="text"

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

哪个转义引号.

inline ="none" 我不太了解,因为它什么也没做

inline="none" I do not really understand, as it does nothing

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

说实话,我不知道如何解决这个问题,希望在那里的任何人都知道如何处理.

To be honest I have no idea how to solve this issue and hopefully anybody out there knows how to deal with this.

非常感谢 干杯 约翰

推荐答案

我会更改方法.

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

Thymeleaf easily allows you to add model variables in your templates to be used in Javascript. In my implementations, I usually put those variables somewhere before the closing header tag; to ensure they're on the page once the JS loads.

我当然让模板决定要加载的内容.如果要显示图库,则按需要进行渲染,并使用数据属性来定义与某些JS代码相关的图库.然后给自己写一个漂亮的 jQuery插件来处理您的图片库.

I let the template decide what exactly to load, of course. If you're displaying a gallery, then render it as you would and use data attributes to define the gallery that relates to some JS code. Then write yourself a nice jQuery plugin to handle your gallery.

一个相对基本的例子:

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

Default Layout Decorator: 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插件.

The thing to notice here is the inclusion of the generic footer scripts and then a layout:fragment div defined. This layout div is what we're going to use to include our jQuery plugin needed for the gallery.

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

File with general scripts: 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层提供了有用的上下文路径,并为

提供了唯一的上下文路径.然后根据我们的模型定义和分配图库对象.同样,在此示例中,页脚片段会加载jQuery库和主站点JS文件.

In the scripts file, there are 2 fragments, which are included from the decorator. In the header fragment, a helpful context path is included for the JS layer, as well as a defaultTheme just for the hell of it. A gallery object is then defined and assigned from our model. The footer fragment loads the jQuery library and a main site JS file, again for purposes of this example.

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

A page with a lazy-loaded gallery: 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插件中用来初始化图库的属性.

Our products page doesn't have much on it. Using the default decorator, this page overrides the page title in the head. Our content fragment includes a title in an h1 tag and an empty div with a data-gallery attribute. This attribute is what we'll use in our jQuery plugin to initialize the gallery.

该值设置为lazyload,因此我们的插件知道我们需要在某个位置的某个变量集中找到图像ID.如果我们的插件唯一支持的是延迟加载的图片库,则可能很容易将其清空.

The value is set to lazyload, so our plugin knows that we need to find the image IDs in some variable set somewhere. This could have easily been empty if the only thing our plugin supports is a lazyloaded gallery.

因此,该布局加载了一些默认脚本,并巧妙地放置了layout:fragments,您允许网站的某些部分加载独立于其余部分的库.

So the layout loads some default scripts and with cleverly placed layout:fragments, you allow certain sections of the site to load libraries independent of the rest.

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

Here's a basic Spring controller example, to work with our app: 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";
  }
}

在product方法中将Gallery类内联扔掉,以简化此处的示例.这可以很容易地成为某种类型的服务或存储库,该服务或存储库返回标识符数组或您需要的任何内容.

The Gallery class was tossed inline in the products method, to simplify our example here. This could easily be a service or repository of some type that returns an array of identifiers, or whatever you need.

我们创建的jQuery插件可能类似于:my_gallery.js

The jQuery plugin that we created, could look something like so: 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));

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

The final rendering of the products page would look like so:

<!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插件,初始化图库所需的所有内容均应加载并准备就绪.

As you can see, Thymeleaf does a pretty good job of translating your model to valid JS and actually adds the quotes where needed and escapes them as well. Once the page finishes rendering, with the jQuery plugin at the end of the file, everything needed to initialize the gallery should be loaded and ready to go.

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

This is not a perfect example, but I think it's a pretty straight-forward design pattern for a web app.

这篇关于Thymeleaf th:inline ="javascript"问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆