【问题标题】:Templating variable doesn't render as expected模板变量未按预期呈现
【发布时间】:2018-02-22 20:00:36
【问题描述】:

我想测试 John Resig 微模板引擎https://johnresig.com/blog/javascript-micro-templating/,但它不渲染 123 而是显示文字模板

更新代码出现错误

未捕获的类型错误:无法读取 null 的属性“innerHTML” 在 tmpl (index2.html:19) 在 index2.html:58

  <!DOCTYPE html>
  <html>
  <head>
      <meta charset="utf-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>Test</title>
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <script>
              // Simple JavaScript Templating
              // John Resig - https://johnresig.com/ - MIT Licensed
              (function(){
                var cache = {};

                this.tmpl = function tmpl(str, data){
                  // Figure out if we're getting a template, or if we need to
                  // load the template - and be sure to cache the result.
                  var fn = !/\W/.test(str) ?
                    cache[str] = cache[str] ||
                      tmpl(document.getElementById(str).innerHTML) :

                    // Generate a reusable function that will serve as a template
                    // generator (and which will be cached).
                    new Function("obj",
                      "var p=[],print=function(){p.push.apply(p,arguments);};" +

                      // Introduce the data as local variables using with(){}
                      "with(obj){p.push('" +

                      // Convert the template into pure JavaScript
                      str
                        .replace(/[\r\t\n]/g, " ")
                        .split("<%").join("\t")
                        .replace(/((^|%>)[^\t]*)'/g, "$1\r")
                        .replace(/\t=(.*?)%>/g, "',$1,'")
                        .split("\t").join("');")
                        .split("%>").join("p.push('")
                        .split("\r").join("\\'")
                    + "');}return p.join('');");

                  // Provide some basic currying to the user
                  return data ? fn( data ) : fn;
                };
              })();    
                  </script>      

  </head>
  <body>
  <script>
  var data = [
    {
      "id":"123",
    },
    {
      "id":"456",
    }          
  ]
  var id1 = data[0].id
  document.body.innerHTML = tmpl("item_tmpl", id1);

  </script>    
  <script type="text/html" id="item_tmpl"> 
    <div>
        <%=id1%>
    </div>
  </script>


  </body>
  </html>

【问题讨论】:

  • 您是否尝试查看控制台日志?应该是脚本错误
  • @Pierre 在 chrome 控制台中没有错误。

标签: javascript templating


【解决方案1】:

你忘了初始化模板函数:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>
            // Simple JavaScript Templating
            // John Resig - https://johnresig.com/ - MIT Licensed
            (function(){
              var cache = {};

              this.tmpl = function tmpl(str, data){
                // Figure out if we're getting a template, or if we need to
                // load the template - and be sure to cache the result.
                var fn = !/\W/.test(str) ?
                  cache[str] = cache[str] ||
                    tmpl(document.getElementById(str).innerHTML) :

                  // Generate a reusable function that will serve as a template
                  // generator (and which will be cached).
                  new Function("obj",
                    "var p=[],print=function(){p.push.apply(p,arguments);};" +

                    // Introduce the data as local variables using with(){}
                    "with(obj){p.push('" +

                    // Convert the template into pure JavaScript
                    str
                      .replace(/[\r\t\n]/g, " ")
                      .split("<%").join("\t")
                      .replace(/((^|%>)[^\t]*)'/g, "$1\r")
                      .replace(/\t=(.*?)%>/g, "',$1,'")
                      .split("\t").join("');")
                      .split("%>").join("p.push('")
                      .split("\r").join("\\'")
                  + "');}return p.join('');");

                // Provide some basic currying to the user
                return data ? fn( data ) : fn;
              };
            })();    
                </script>      

</head>
<body>
  <div id="container"></div>
<script type="text/html" id="item_tmpl"> 
  <div>
      <%=id1%>
  </div>
</script>
<script>
var data = [
  {
    "id":"123",
  },
  {
    "id":"456",
  }          
]
var id1 = data[0].id
var container = document.getElementById('container');
container.innerHTML = tmpl("item_tmpl", id1);
</script>
</body>
</html>

【讨论】:

  • 奇怪的是,当我在我的电脑上尝试你的代码时它不起作用,你能看到上面的更新吗,谢谢。
  • @user310291 我更换了整个身体。您可能应该使用带有 id 的 div ,就像您提供的示例链接一样。您必须注意访问/调用对象/函数的顺序。您正在请求正文本身访问文档正文。我的示例中的顶部脚本应该在正文中。
  • 感谢现在可以工作了 :) 过去使用过那个库很奇怪,不记得我遇到过那种问题。
  • 你有什么模板引擎不需要将 html 部分包装在脚本标签内,因为当我使用复杂的动态主题时,他们似乎不喜欢那样。
  • @user310291 个人而言,我喜欢简单明了的解决方案。因此,当我开始考虑动态模板时,我会停止深入挖掘并考虑整个概念。大多数情况下,如果 web 应该是动态的,那么 reactjs/angularjs 和类似的框架是可行的..但这只是我的意见..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 2017-02-23
  • 2018-10-01
  • 2014-09-29
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多