spring Thymeleaf th:inline="javascript" 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32596600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Thymeleaf th:inline="javascript" issue
提问by John B.
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。
This final piece of javascript code then should be added inside the $(document).ready { }part of my html page.
最后一段 javascript 代码应该添加到我的 html 页面的$(document).ready { }部分中。
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="javascript",代码会被引用,因为我的 getter 是一个字符串(这就是 Thymeleaf 文档中提到的方式,但这不是我需要的;-)
If I use inline="text" in is not quoted but all quotes are escaped instead ;-) - also nice but unusable 8)
如果我使用 inline="text" in 没有被引用,但所有引号都被转义了 ;-) - 也很好但无法使用 8)
If I try inline="none" nothing happens.
如果我尝试 inline="none" 没有任何反应。
Here are the examples
以下是示例
My model getter created the following Javascript code.
我的模型 getter 创建了以下 Javascript 代码。
PageHelper class
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')";
}
So if I now try inline="javascript"
所以如果我现在尝试inline="javascript"
<script th:inline="javascript">
/*<![CDATA[*/
jQuery().ready(function(){
/*[[${pageHelper.documentReady}]]*/
});
/*]]>*/
</script>
it will be rendered to
它将被渲染为
<script>
/*<![CDATA[*/
jQuery().ready(function(){
'PhotoGallery.load(8,5,3,2).loadTheme(name=\'basic\')'
});
/*]]>*/
</script>
Which doesn't help as it is a String literal, nothing more (this is how Thymeleaf deals with it).
这无济于事,因为它是一个字符串文字,仅此而已(这就是 Thymeleaf 处理它的方式)。
So if I try inline="text"instead
所以如果我尝试inline="text"代替
<script>
/*<![CDATA[*/
jQuery().ready(function(){
PhotoGallery.load(8,5,3,2).loadTheme(name='basic')
});
/*]]>*/
</script>
Which escapes the quotes.
哪个逃脱了引号。
inline="none"I do not really understand, as it does nothing
inline="none"我不太明白,因为它什么也没做
<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.
老实说,我不知道如何解决这个问题,希望那里的任何人都知道如何处理这个问题。
Many thanks in advance Cheers John
非常感谢提前干杯约翰
采纳答案by yorgo
I would change the approach.
我会改变方法。
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.
Thymeleaf 允许您轻松地在模板中添加模型变量以在 Javascript 中使用。在我的实现中,我通常将这些变量放在结束标头标记之前的某个位置;以确保它们在 JS 加载后位于页面上。
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 pluginto handle your gallery.
当然,我让模板决定加载什么。如果您正在显示图库,则按照您的意愿渲染它并使用数据属性来定义与某些 JS 代码相关的图库。然后为自己编写一个不错的jQuery 插件来处理您的画廊。
A relatively basic example:
一个比较基础的例子:
Default Layout Decorator: layout/default.html
默认布局装饰器: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>
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.
这里要注意的是包含通用页脚脚本,然后layout:fragment
定义了一个div。我们将使用这个布局 div 来包含画廊所需的 jQuery 插件。
File with general scripts: fragments/scripts.html
带有通用脚本的文件: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>
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.
在脚本文件中,有 2 个片段,它们来自装饰器。在标题片段中,包含了一个有用的 JS 层的上下文路径,以及defaultTheme
它的地狱。然后从我们的模型中定义和分配一个画廊对象。页脚片段加载了 jQuery 库和一个主站点 JS 文件,同样出于本示例的目的。
A page with a lazy-loaded gallery: products.html
带有延迟加载图库的页面: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>
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.
我们的产品页面上没有太多内容。使用默认装饰器,此页面会覆盖头部中的页面标题。我们的内容片段包括一个 h1 标签中的标题和一个带有 data-gallery 属性的空 div。我们将在 jQuery 插件中使用此属性来初始化图库。
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.
该值设置为lazyload,所以我们的插件知道我们需要在某个变量集中找到图像ID。如果我们的插件支持的唯一内容是延迟加载的图库,则这很容易为空。
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.
因此布局加载了一些默认脚本并巧妙地放置了layout:fragments
,您允许站点的某些部分独立于其余部分加载库。
Here's a basic Spring controller example, to work with our app: MyController.java
这是一个基本的 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";
}
}
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.
Gallery 类在 products 方法中被内联抛出,以简化我们的示例。这很容易成为某种类型的服务或存储库,返回标识符数组,或者您需要的任何内容。
The jQuery plugin that we created, could look something like so: my_gallery.js
我们创建的 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));
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>
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.
正如您所看到的,Thymeleaf 在将您的模型转换为有效的 JS 方面做得非常好,并且实际上在需要的地方添加了引号并对其进行了转义。一旦页面完成渲染,在文件末尾使用 jQuery 插件,初始化画廊所需的一切都应该被加载并准备就绪。
This is nota perfect example, but I think it's a pretty straight-forward design pattern for a web app.
这不是一个完美的例子,但我认为这是一个非常简单的网络应用程序设计模式。
回答by Rassoul Mansoury
instead of ${pageHelper.documentReady}
use ${pageHelper.documentReady}
而不是${pageHelper.documentReady}
使用${pageHelper.documentReady}