如何在EJS模板中渲染变量存储的EJS代码字符串并使其正常生效?
问题根源
你遇到的两个问题本质都是混淆了EJS服务端渲染时机和客户端JS执行时机,再加上语法使用错误导致的:
- EJS的模板解析、
include指令执行都是在页面返回给浏览器之前,在服务端完成的。你后续在客户端通过.append()插入的带<%= %>、<%- include %>语法的内容,浏览器不会再做EJS解析,自然不会生效。 JSON.stringify()的作用是把JS值转为合法的JSON字符串,本身就会给原始字符串外层包裹双引号,这就是你输出内容外层多引号的原因。
可行解决方案
根据你的需求(动态切换数据库存储的EJS模板),推荐两种适配不同场景的实现方案:
方案1:服务端预渲染所有模板,客户端直接切换
适合模板数量少、渲染数据不会频繁在客户端更新的场景
- 服务端渲染阶段,提前把所有需要用到的EJS模板都渲染为最终HTML片段,存入客户端JS变量或者页面隐藏容器中:
<script> // 服务端提前渲染所有模板,存入JS对象 const renderedTplMap = { // 注意这里JSON.stringify仅用来将HTML转为合法JS字符串,不会产生多余显示引号 tpl1: <%- JSON.stringify(renderedTpl1) %>, tpl2: <%- JSON.stringify(renderedTpl2) %> } </script>
- 客户端点击切换按钮时,直接取出对应HTML插入容器即可:
wrapper.append(`<div class="container canvas" id="toCan">${renderedTplMap.tpl1}</div>`)
方案2:客户端引入EJS运行时,动态编译模板
适合模板存储在数据库、需要动态拉取、渲染数据可能在客户端更新的场景,完全满足动态切换需求
- 首先将EJS客户端运行时(ejs.min.js)存入你的静态资源目录,在页面中引入。
- 服务端将数据库存储的原始EJS模板字符串、渲染所需数据都传递给客户端:
<script> // 数据库存储的原始EJS模板字符串 const rawTpl = <%- JSON.stringify(stringOfCode) %> // 渲染模板需要用到的数据 const renderData = { user: <%- JSON.stringify(user) %> } </script>
- 点击切换按钮时,在客户端完成模板编译、渲染再插入:
// 编译原始模板 const compiledTpl = ejs.compile(rawTpl) // 传入数据得到最终HTML const finalHtml = compiledTpl(renderData) // 插入容器 wrapper.append(`<div class="container canvas" id="toCan">${finalHtml}</div>`)
如果需要切换其他模板,只要替换rawTpl的值重复上述编译渲染流程即可。
内容的提问来源于stack exchange,提问作者VortexSensei
相关产品推荐
相关产品推荐

