需要 Handlebars.js 呈现对象数据而不是“[ Object Object ]”

我正在使用 Handlebar 模板,JSON 数据已经在[ Object Object ]中表示了,我如何在 Handlebar 之外解析这些数据?例如,我试图通过一个句柄标记在页面上填充一个 JavaScript 变量,但这不起作用。

有什么建议吗? 谢谢!

编辑:

为了澄清,我使用 ExpressJSw/Handlebar 进行模板化:

var user = {}
user = {'id' : 123, 'name' : 'First Name'}


res.render('index', {user : user});

然后在 index.hbs 模板中,我现在有了一个 {{user}}对象。我可以使用 {{#each}}迭代遍历对象。但是,我也在使用 Backbonejs,我想把这些数据传递给一个视图,比如:

myView = new myView({
user : {{user}}
});

问题是 {{user}}只是在源代码中显示 [Object object]。如果我把它放在 console. log 中,就会得到一个错误,表示‘意外标识符’。

115824 次浏览

You are trying to pass templating syntax \{\{ }} inside a JSON object which is not valid.

You may need to do this instead:

myView = new myView({ user : user });

When outputting \{\{user}}, Handlebars will first retrieve the user's .toString() value. For plain Objects, the default result of this is the "[object Object]" you're seeing.

To get something more useful, you'll either want to display a specific property of the object:

\{\{user.id}}
\{\{user.name}}

Or, you can use/define a helper to format the object differently:

Handlebars.registerHelper('json', function(context) {
return JSON.stringify(context);
});
myView = new myView({
user : \{\{{json user}}} // note triple brackets to disable HTML encoding
});

I'm using server-side templating in node-js, but this may apply client-side as well. I register Jonathan's json helper in node. In my handler, I add context (such as addressBook) via res.locals. Then I can store the context variable client-side as follows:

<script>
\{\{#if addressBook}}
console.log("addressBook:", \{\{{json addressBook}}});
window.addressBook = \{\{{json addressBook}}};
\{\{/if}}
</script>

Note the triple curlies (as pointed out by Jim Liu).

You can simple stringify the JSON:

var user = {}
user = {'id' : 123, 'name' : 'First Name'};
// for print
user.stringify = JSON.stringify(user);

Then in template print by:

\{\{{user.stringify}}};

If you want more control over the output formatting you can write your own helper. This one has a recursive function to traverse nested objects.

  Handlebars.registerHelper('objToList', function(context) {
function toList(obj, indent) {
var res=""
for (var k in obj) {
if (obj[k] instanceof Object) {
res=res+k+"\n"+toList(obj[k], ("   " + indent)) ;
}
else{
res=res+indent+k+" : "+obj[k]+"\n";
}
}
return res;
}
return toList(context,"");
});

We used handlebars for email templates and this proved useful for a user like the following

{
"user": {
"id": 123,
"name": "First Name",
"account": {
"bank": "Wells Fargo",
"sort code": " 123-456"
}
}
}

In the Node Router - Stringify the response object. See below line.

 response.render("view", {responseObject:JSON.stringify(object)});

In HTML Script tag - user Template literals (Template strings) and use JSON.parse.

const json= `\{\{{responseObject}}}`;
const str = JSON.parse(json);

Worked like a charm!

You can render the keys/values of a list or object in a Handlebars template like this:

\{\{#each the_object}}
\{\{@key}}: \{\{this}}
\{\{/each}}

To condense (what I found to be) the most helpful answers...

JSON helper for handlebars (credit):

Handlebars.registerHelper("json", function (context) {
return JSON.stringify(context);
});

JSON helper for express-handlebars (credit and I updated to newest conventions):

app.engine(
"handlebars",
exphbs.engine({
defaultLayout: "main",
helpers: {
json: function (context) {
return JSON.stringify(context);
}
}
})
);

And then on the templating side: \{\{json example}}

Just improving the answer from @sajjad.

Adding a 'pre' tag will make it look a lot nicer.

<pre>
\{\{#each the_object}}
\{\{@key}}: \{\{this}}
\{\{/each}}
</pre>