Handlebars.js: Kesalahan: Objek templat tidak dikenal: string saat menggunakan templat yang telah dikompilasi dengan .template()

Dibuat pada 12 Des 2014  ·  4Komentar  ·  Sumber: handlebars-lang/handlebars.js

Saya mencoba mendaftarkan sebagian, yang menurut dokumen harus dilakukan seperti ini:

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

handlebars.registerPartial('stuff', template)

Namun metode .template() menghasilkan kesalahan ini:

Error: Unknown template object: string

Saya dapat melihat bahwa compiledPartial atas memang string yang terlihat seperti objek:

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

WTF?

Node 0.10.25, Setang 2.0.0

Komentar yang paling membantu

Saya sedang menulis aplikasi sisi server yang harus dapat mengkompilasi kedua templat (dan kemudian mengirimkannya ke klien jika mereka perlu dirender ulang dengan konteks baru) dan juga merendernya ke HTML (untuk flicker/ penundaan pada klien + peningkatan SEO). Sepertinya saya perlu memanggil precompile dan compile secara terpisah atau saya perlu eval output serialized precompiler. Tak satu pun dari pendekatan itu terasa sangat elegan, jadi apakah saya melewatkan sesuatu atau aplikasi saya tidak biasa? (BTW, aplikasi ini ditulis dalam Java tetapi menggunakan mesin JavaScript [Rhino/Nashorn] bawaan untuk bagian templating; semoga itu tidak masalah.)

Jika ada orang lain yang bingung dengan dokumentasi untuk prakompilasi dan berakhir di sini, saya telah menulis sebuah contoh untuk mengilustrasikan apa yang sedang terjadi. (Sebenarnya, saya menulisnya karena saya mencoba mencari tahu apa yang saya lakukan salah.)

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)");
});

Semua 4 komentar

Metode precompiler dimaksudkan untuk membuat serial template dan kemudian metode template digunakan untuk memulihkannya pada klien. Jika Anda mencoba mengevaluasi template dalam proses yang sama maka Anda harus menggunakan Handlebars.compile secara langsung.

Terima kasih atas jawabannya. Tampaknya dokumen lebih diarahkan untuk menggunakan Handlebars di sisi klien, karena dimungkinkan untuk meneruskan string parsial yang tidak dikompilasi ke metode registerPartial() , jika Anda hanya menggunakan Handlebars di sisi server.

Saya sedang menulis aplikasi sisi server yang harus dapat mengkompilasi kedua templat (dan kemudian mengirimkannya ke klien jika mereka perlu dirender ulang dengan konteks baru) dan juga merendernya ke HTML (untuk flicker/ penundaan pada klien + peningkatan SEO). Sepertinya saya perlu memanggil precompile dan compile secara terpisah atau saya perlu eval output serialized precompiler. Tak satu pun dari pendekatan itu terasa sangat elegan, jadi apakah saya melewatkan sesuatu atau aplikasi saya tidak biasa? (BTW, aplikasi ini ditulis dalam Java tetapi menggunakan mesin JavaScript [Rhino/Nashorn] bawaan untuk bagian templating; semoga itu tidak masalah.)

Jika ada orang lain yang bingung dengan dokumentasi untuk prakompilasi dan berakhir di sini, saya telah menulis sebuah contoh untuk mengilustrasikan apa yang sedang terjadi. (Sebenarnya, saya menulisnya karena saya mencoba mencari tahu apa yang saya lakukan salah.)

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 Anda ingin memanggil kompilasi dan prakompilasi. Kode yang dihasilkan untuk keduanya sangat berbeda dan saya tidak akan menganggap bahwa mencoba toString atau serupa akan bekerja dengan hasil kompilasi, dll.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat