Nodejs Handlebars 例子提示 templateSpec.call is not a function

Nodejs Handlebars 例子提示 templateSpec.call is not a function

http://handlebarsjs.com 上的例子

var source=document.getElementById('entry-template').innerHTML;
var template = Handlebars.compile(source);

提示

TypeError: Handlebars.compile is not a function

然后用 Firebug 看了一个 没有 complie 方法, 有个 template 然后用 template 调用

var template = Handlebars.template(source);

返回是一个函数

template(data) 这样调用提示 templateSpec.call is not a function


5 回复

Node.js Handlebars 例子提示 templateSpec.call is not a function

在使用 Handlebars 渲染模板时,如果遇到 TypeError: Handlebars.compile is not a function 或者 TypeError: templateSpec.call is not a function 的错误,通常是因为你没有正确地导入或初始化 Handlebars 库。

示例代码

假设你有一个简单的 HTML 文件,其中包含一个 Handlebars 模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Handlebars Example</title>
    <script src="https://cdn.jsdelivr.net/npm/handlebars/dist/handlebars.min.js"></script>
</head>
<body>
    <script id="entry-template" type="text/x-handlebars-template">
        <div>
            <h1>{{title}}</h1>
            <p>{{body}}</p>
        </div>
    </script>

    <script>
        // 获取模板字符串
        var source = document.getElementById('entry-template').innerHTML;

        // 编译模板
        var template = Handlebars.compile(source);

        // 准备数据
        var data = {
            title: 'Hello World',
            body: 'This is a test.'
        };

        // 渲染模板
        var result = template(data);

        // 输出结果
        console.log(result);
    </script>
</body>
</html>

解决方法

  1. 确保正确引入 Handlebars 库: 确保你在页面中正确地引入了 Handlebars 库。你可以通过 CDN 引入:

    <script src="https://cdn.jsdelivr.net/npm/handlebars/dist/handlebars.min.js"></script>
    
  2. 使用正确的编译方法

    • 如果你使用的是较新版本的 Handlebars,应该使用 Handlebars.compile() 方法。
    • 如果你使用的是较旧版本的 Handlebars,可能会看到 Handlebars.template() 方法。在这种情况下,你需要将数据传递给该方法的结果。
  3. 检查模板字符串: 确保模板字符串正确无误,并且没有语法错误。

  4. 调试: 使用浏览器的开发者工具(如 Firebug)来检查 Handlebars 对象是否正确加载,并查看是否有其他错误信息。

示例代码解析

  • 获取模板字符串

    var source = document.getElementById('entry-template').innerHTML;
    

    这行代码从 HTML 中获取模板字符串。

  • 编译模板

    var template = Handlebars.compile(source);
    

    使用 Handlebars.compile() 方法编译模板字符串。

  • 准备数据

    var data = {
        title: 'Hello World',
        body: 'This is a test.'
    };
    

    定义用于渲染的数据对象。

  • 渲染模板

    var result = template(data);
    

    使用编译后的模板函数和数据对象渲染模板。

  • 输出结果

    console.log(result);
    

    将渲染结果输出到控制台。

通过以上步骤,你应该能够解决 templateSpec.call is not a function 的问题。如果问题仍然存在,请检查 Handlebars 版本和引入方式是否正确。


不可能没有compile方法吧。至于template方法,貌似不是你这样用的。

看下Handlebars.template的定义:

function template(templateSpec, env) {
    if (!env) {
      throw new Exception("No environment passed to template");
    }
// Note: Using env.VM references rather than local var references throughout this section to allow
// for external users to override these as psuedo-supported APIs.
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
  var result = env.VM.invokePartial.apply(this, arguments);
  if (result != null) { return result; }

  if (env.compile) {
    var options = { helpers: helpers, partials: partials, data: data };
    partials[name] = env.compile(partial, { data: data !== undefined }, env);
    return partials[name](context, options);
  } else {
    throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
  }
};

// Just add water
var container = {
  escapeExpression: Utils.escapeExpression,
  invokePartial: invokePartialWrapper,
  programs: [],
  program: function(i, fn, data) {
    var programWrapper = this.programs[i];
    if(data) {
      programWrapper = program(i, fn, data);
    } else if (!programWrapper) {
      programWrapper = this.programs[i] = program(i, fn);
    }
    return programWrapper;
  },
  merge: function(param, common) {
    var ret = param || common;

    if (param &amp;&amp; common &amp;&amp; (param !== common)) {
      ret = {};
      Utils.extend(ret, common);
      Utils.extend(ret, param);
    }
    return ret;
  },
  programWithDepth: env.VM.programWithDepth,
  noop: env.VM.noop,
  compilerInfo: null
};

return function(context, options) {
  options = options || {};
  var namespace = options.partial ? options : env,
      helpers,
      partials;

  if (!options.partial) {
    helpers = options.helpers;
    partials = options.partials;
  }
  var result = templateSpec.call(
        container,
        namespace, context,
        helpers,
        partials,
        options.data);

  if (!options.partial) {
    env.VM.checkRevision(container.compilerInfo);
  }

  return result;
};

}

传入的参数是一个function,这也是为什么你调用Handlebars.template(source)之后会报 templateSpec.call is not a function 的错误。

按官网的例子写的

<script type="text/x-handlebars-template"  id='xx'>
&lt;h1&gt;{{title}}&lt;/h1&gt;
&lt;ul&gt;
    {{#names}}
        &lt;li&gt;{{name}}&lt;/li&gt;
    {{/names}}
&lt;/ul&gt;

</script>

<script type=“text/javascript”> var source=document.getElementById(‘xx’).innerHTML; var template = Handlebars.compile(source); console.log(template); var data = {“title”: “Story”, “names”: [{“name”: “Tarzan”}, {“name”: “Jane”}]}; console.log(template(data)); </script>

这个问题通常是因为Handlebars库版本不匹配或加载方式不正确导致的。以下是可能的解决方案和一个完整的示例代码。

解决方案

  1. 确保Handlebars库正确加载:确保你在HTML文件中通过<script>标签正确加载了Handlebars库。
  2. 使用正确的编译方法:根据你的Handlebars版本,使用正确的编译方法。如果你使用的是较新的Handlebars版本(例如v4.x及以上),应该使用Handlebars.compile;如果是较旧版本(例如v3.x及以下),则可能需要使用Handlebars.template

示例代码

假设你已经通过CDN正确加载了Handlebars库,你可以使用以下代码来创建和编译模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Handlebars Example</title>
    <!-- 引入Handlebars库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>
</head>
<body>
    <script id="entry-template" type="text/x-handlebars-template">
        <div>
            {{name}}
            <br>
            {{age}}
        </div>
    </script>

    <script>
        // 获取模板源代码
        var source = document.getElementById('entry-template').innerHTML;

        // 使用Handlebars.compile方法编译模板
        var template = Handlebars.compile(source);

        // 准备数据
        var data = {
            name: "John Doe",
            age: 30
        };

        // 渲染模板
        var result = template(data);

        // 输出渲染结果
        console.log(result);
    </script>
</body>
</html>

解释

  1. 引入Handlebars库:在HTML文件中通过CDN引入Handlebars库。
  2. 定义模板:使用<script>标签定义模板,并设置类型为text/x-handlebars-template
  3. 获取模板源代码:通过document.getElementById获取模板源代码。
  4. 编译模板:使用Handlebars.compile方法编译模板。
  5. 准备数据:定义一个JavaScript对象作为模板的数据。
  6. 渲染模板:将数据传递给编译后的模板函数以生成最终的HTML字符串。
  7. 输出结果:将渲染结果输出到控制台。

如果问题仍然存在,请检查你的Handlebars版本是否正确,并确保所有依赖项都已正确加载。

回到顶部