Handlebars.js: 错误:未知模板对象:使用带有 .template() 的预编译模板时的字符串

创建于 2014-12-12  ·  4评论  ·  资料来源: handlebars-lang/handlebars.js

我正在尝试注册一个部分,根据文档应该这样做:

var partialString = fs.readFileSync(filename), {encoding: 'utf8'})
var compiledPartial = handlebars.precompile(partialString)
var template = handlebars.template(compiledPartial)

handlebars.registerPartial('stuff', template)

但是.template()方法会产生这个错误:

Error: Unknown template object: string

我可以看到上面的compiledPartial确实是一个看起来像一个对象的字符串:

{"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<div>Stuff</div>\n";
},"useData":true}

跆拳道?

节点 0.10.25,把手 2.0.0

最有用的评论

我正在编写一个服务器端应用程序,它需要能够预编译模板(然后将它们交付给客户端,以防它们需要使用新上下文重新呈现)并将它们呈现为 HTML(为了不那么明显的闪烁/客户端延迟 + 改进的 SEO)。 看来我要么需要分别调用precompilecompile要么我需要eval序列化的预编译器输出。 这两种方法都感觉很优雅,所以我是否遗漏了什么或者我的应用程序不寻常? (顺便说一句,这个应用程序是用 Java 编写的,但在模板部分使用了内置的 [Rhino/Nashorn] JavaScript 引擎;希望这无关紧要。)

如果其他人对预编译

var templateSources = {
    hi: "Hi, {{name}}.",
    bye: "Goodbye, {{name}}."
};
var compiledTemplates = {};
var serializedTemplates = {};
var deserializedTemplates = {};

Object.keys(templateSources).forEach(function(name) {
    // Use compile method to generate actual executable template (function)
    compiledTemplates[name] = Handlebars.compile(templateSources[name]);
    // Use precompile method to generate serialized JS (string)
    serializedTemplates[name] = Handlebars.precompile(templateSources[name]);
    // If we really want, we can deserialize these 
    deserializedTemplates[name] = Handlebars.template(evalPrecompiledTemplate(serializedTemplates[name]));
});

// (Yes, I know eval is dangerous)
function evalPrecompiledTemplate(s) {
    return eval("(function(){return " + s + "}());");
}

// Quick demonstration that these template functions work the same
var context = {
    name: "John Smith"
};

// Output: 
// Rendering template named hi with context: Object {name: "John Smith"}
// Hi, John Smith.(compiled)
// Hi, John Smith.(precompiled/deserialized)
// Rendering template named bye with context: Object {name: "John Smith"}
// Goodbye, John Smith.(compiled)
// Goodbye, John Smith.(precompiled/deserialized)
Object.keys(templateSources).forEach(function(name) {
  console.log("Rendering template named " + name + " with context:", context);
  console.log(compiledTemplates[name](context) + "(compiled)");
  console.log(deserializedTemplates[name](context) + "(precompiled/deserialized)");
});

所有4条评论

precompiler方法用于序列化模板,然后template方法用于在客户端恢复它。 如果您尝试在同一过程中评估模板,则应直接使用Handlebars.compile

谢谢你的回答。 似乎文档更适合在客户端使用 Handlebars,因为如果您仅在服务器端使用 Handlebars,则可以仅将未编译的部分字符串传递给registerPartial()方法。

我正在编写一个服务器端应用程序,它需要能够预编译模板(然后将它们交付给客户端,以防它们需要使用新上下文重新呈现)并将它们呈现为 HTML(为了不那么明显的闪烁/客户端延迟 + 改进的 SEO)。 看来我要么需要分别调用precompilecompile要么我需要eval序列化的预编译器输出。 这两种方法都感觉很优雅,所以我是否遗漏了什么或者我的应用程序不寻常? (顺便说一句,这个应用程序是用 Java 编写的,但在模板部分使用了内置的 [Rhino/Nashorn] JavaScript 引擎;希望这无关紧要。)

如果其他人对预编译

var templateSources = {
    hi: "Hi, {{name}}.",
    bye: "Goodbye, {{name}}."
};
var compiledTemplates = {};
var serializedTemplates = {};
var deserializedTemplates = {};

Object.keys(templateSources).forEach(function(name) {
    // Use compile method to generate actual executable template (function)
    compiledTemplates[name] = Handlebars.compile(templateSources[name]);
    // Use precompile method to generate serialized JS (string)
    serializedTemplates[name] = Handlebars.precompile(templateSources[name]);
    // If we really want, we can deserialize these 
    deserializedTemplates[name] = Handlebars.template(evalPrecompiledTemplate(serializedTemplates[name]));
});

// (Yes, I know eval is dangerous)
function evalPrecompiledTemplate(s) {
    return eval("(function(){return " + s + "}());");
}

// Quick demonstration that these template functions work the same
var context = {
    name: "John Smith"
};

// Output: 
// Rendering template named hi with context: Object {name: "John Smith"}
// Hi, John Smith.(compiled)
// Hi, John Smith.(precompiled/deserialized)
// Rendering template named bye with context: Object {name: "John Smith"}
// Goodbye, John Smith.(compiled)
// Goodbye, John Smith.(precompiled/deserialized)
Object.keys(templateSources).forEach(function(name) {
  console.log("Rendering template named " + name + " with context:", context);
  console.log(compiledTemplates[name](context) + "(compiled)");
  console.log(deserializedTemplates[name](context) + "(precompiled/deserialized)");
});

@jacobq你会想要调用编译和预编译。 两者生成的代码非常不同,我不认为尝试 toString 或类似方法会与编译输出等一起工作。

此页面是否有帮助?
0 / 5 - 0 等级