不能在客户端上呈现EJS模板
Can't Render EJS Template on Client
我正在编写express上的应用程序,并且我使用ejs作为视图/模板引擎。
在路径/artists
,我渲染视图artists.ejs
,其中有艺术家的封面。当点击一个封面,我想要一个AJAX调用来检索相应的数据,把它放在我的模板/视图的艺术家artist.ejs
和显示这个模板在我的HTML下的封面。
我看到过这个相关的问题,但它并没有解决我的用例。
一切似乎都很清楚,但我不能用模板渲染数据。我想在服务器端编译模板,将其发送到客户端准备使用,然后在需要时使用从AJAX调用接收到的数据填充它。
我做了什么:
调用/artists
时,在服务器端使用ejs.compile(str, opt)
进行编译:
router.get('/artists', function(req, res) {
// Compile artist template
fs.readFile('views/artist.ejs', "utf-8", function(err, template) { // Convert template file to string
artist_template = ejs.compile(template); // Compile template
res.render('artists.ejs', {template: artist_template}); // render page with compiled template
});
我负责将文件转换为String,因为ejs编译器只适用于String(与Jade .compileFile相比)
然后在客户端,我抓取函数:
<script>
var template = <%= template %>
</script>
然后在另一个脚本中,我使用AJAX调用检索数据:
$.get('/artists/'+artist_name, function(data) {
var html = template({artist: data});
$('#artist-page').html(html);
}
但是当我打电话时,我收到:
Uncaught ReferenceError: fn is not defined
当我调用模板fn
时,我收到:
Uncaught ReferenceError: opts is not defined.
函数fn
是硬编码的吗?我已经阅读了EJS和Jade文档,但是几乎没有关于我的问题的相关信息。
我是否也需要客户端模板?
我最终找到了一个解决我的问题的方法,我理解了你的回答,你可以用两种不同的方式进行:
1)我所做的:读取并保存模板为字符串,然后用ejs运行时脚本在客户端渲染它。
// In controller.js
var templates = {};
templates.template1 = fs.readFileSync(filePath1, 'utf-8'); // Read template as a string
templates.template2 = fs.readFileSync(filePath2, 'utf-8');
...
res.render('app.ejs', {templates: templates}); // Send templates in view
// In view app.ejs
<script type="text/javascript">
var templates = <%- JSON.stringify(templates) %>; // Get templates object (object of strings)
</script>
<script type="text/javascript" src="/JS/ejs.min.js"></script> <!-- Load ejs RunTime -->
// In site.js - javascript client/public file
$.get('/artists', function(data) {
var html = ejs.render(templates.template1, data); // Render ejs client side with EJS script (template1 corresponds to the artists template)
$('#artists-wrapper').html(html); // Sets HTML
});
因此,我在第一页加载时发送所有模板,然后在客户端呈现所请求的页面。根据我所读到的,有趣的是,您只通过AJAX调用发送JSON对象(您的数据),而不是整个页面,使您的请求变得轻松。只有第一次加载的所有模板都很重。
2)我想做什么根据@RyanZim回答:编译模板服务器端成函数,发送它们,然后在客户端调用它们:模板(数据)。如果我理解得好,在这种情况下不需要EJS客户端库,我的模板不再是字符串,而是函数:
// In controller.js
var templates = {};
templates.template1 = ejs.compile(fs.readFileSync(filePath1, 'utf-8'), {client: true}); // Get template as a function
templates.template2 = ejs.compile(fs.readFileSync(filePath2, 'utf-8'), {client: true});
...
res.render('app.ejs', {templates: templates}); // Send templates in view
然而,我不能得到他们在我的观点:
<script type="text/javascript">
var templates = <%- JSON.stringify(templates) %>; // Get templates object (object of functions)
</script>
不能工作。它们是我发送之前服务器上的函数,但是我不知道如何恢复它们。你有什么主意吗?
我尝试了一个解决方法,在发送它们之前将它们更改为String:
templates.template1 = templates.template1.toString();
发送它们,然后在客户端,将它们转换回函数:
var template = new Function(templates.template1);
$.get('/artists', function(data) {
var html = template(data);
$('#artists-wrapper').html(html); // Sets HTML
});
但这也行不通。
你知道我错过了什么吗?最后,您是否同意在使用函数之前在服务器端编译它们比在客户端呈现每个模板在计算方面更好?
谢谢你的帮助,希望能帮助到其他人!
在为客户端编译时,需要在服务器端使用client
选项。来自文档:
https://github.com/mde/ejs选项
client
当true
,编译一个可以渲染的函数,而不需要加载EJS Runtime
您的服务器端代码片段应该是:
// Compile artist template
fs.readFile('views/artist.ejs', "utf-8", function(err, template) {
artist_template = ejs.compile(template, {client: true}); // Use client option
res.render('artists.ejs', {template: artist_template});
});
- 如何将JSON数据导入我的ejs模板
- 如何在ejs模板中使用if条件
- EJS模板语言内部逻辑不知何故失败了
- 使用EJS模板进行HTML验证;文本/模板”;元素
- 使用JQuery将ejs模板注入到html中
- 将Parse.File url加载到EJS模板中
- 转义字符串化 JSON 中的单引号,作为 EJS 模板传递以供查看
- ejs 模板数据不会插入到 mongodb 中
- 如何在 expressjs 上调用 ajax 后使用 jquery 渲染部分 ejs 模板
- 节点 JS - 使用路由器添加更多页面(ejs 模板)
- 如何在EJS模板中执行JavaScript代码
- 如何将数据从EJS模板传递到AngularJS控制器
- EJS模板中的外部js
- Webpack文件/图像加载器,用于.ejs模板中的图像
- 如何将jquery与我的Node.js EJS模板一起使用
- 不能在客户端上呈现EJS模板
- 如何从我的ejs模板调用app.js中定义的函数?
- 如何在express中传递数组到ejs模板?
- 如何做多渲染与Node.js, EJS模板和动态文件名
- 如何使用EJS模板语言打破循环