Я пытаюсь зарегистрировать частичное, что, согласно документам, должно быть сделано так:
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
Метод precompiler
предназначен для сериализации шаблона, а затем метод template
используется для его восстановления на клиенте. Если вы пытаетесь оценить шаблон в том же процессе, вам следует использовать Handlebars.compile
напрямую.
Спасибо за ответ. Кажется, что документы больше ориентированы на использование Handlebars на стороне клиента, поскольку можно передать только некомпилированную частичную строку методу registerPartial()
, если вы используете Handlebars только на стороне сервера.
Я пишу серверное приложение, которое должно иметь возможность как предварительно компилировать шаблоны (и затем доставлять их клиенту, если их нужно повторно отрисовать с новым контекстом), так и отображать их в HTML (для менее заметного мерцания / задержка на клиенте + улучшенное SEO). Кажется, мне нужно либо вызвать precompile
и compile
отдельности, либо мне нужно eval
сериализованный вывод прекомпилятора. Ни один из этих подходов не кажется изящным, так что я чего-то упускаю или мое приложение просто необычное? (Кстати, это приложение написано на Java, но с использованием встроенного движка JavaScript [Rhino / Nashorn] для части создания шаблонов; надеюсь, это не имеет значения.)
На случай, если кто-то еще запутался в документации по прекомпиляции и остановился здесь, я написал пример, чтобы проиллюстрировать, что происходит. (На самом деле, я написал это, потому что пытался понять, что я делал не так.)
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 или аналогичный будет работать с выводом компиляции и т. Д.
Самый полезный комментарий
Я пишу серверное приложение, которое должно иметь возможность как предварительно компилировать шаблоны (и затем доставлять их клиенту, если их нужно повторно отрисовать с новым контекстом), так и отображать их в HTML (для менее заметного мерцания / задержка на клиенте + улучшенное SEO). Кажется, мне нужно либо вызвать
precompile
иcompile
отдельности, либо мне нужноeval
сериализованный вывод прекомпилятора. Ни один из этих подходов не кажется изящным, так что я чего-то упускаю или мое приложение просто необычное? (Кстати, это приложение написано на Java, но с использованием встроенного движка JavaScript [Rhino / Nashorn] для части создания шаблонов; надеюсь, это не имеет значения.)На случай, если кто-то еще запутался в документации по прекомпиляции и остановился здесь, я написал пример, чтобы проиллюстрировать, что происходит. (На самом деле, я написал это, потому что пытался понять, что я делал не так.)