问题描述
Handlebars教程正在使用未明确绑定的变量。我是手把的新手,所以我的猜测是正在进行一些隐式绑定。我需要修改代码,但我不知道此绑定如何工作,甚至不知道要搜索什么。
我正在构建一个nodejs应用程序以与Microsoft图形API进行交互。从技术上讲,我使用一些Microsoft tutorial code作为起点。该教程是使用Express和把手构建的。
该教程正在运行,一切正常。
现在,我正在修改代码,但无法发现user
变量的handlebars变量绑定是如何工作的。 user
变量显示在视图index.hbs
和layout.hbs
中,例如:
{{#if user}}
<h4>Welcome {{ user.displayName }}!</h4>
<p>Use the navigation bar at the top of the page to get started.</p>
{{else}}
<a href="/auth/signin" class="btn btn-primary btn-large">Click here to sign in</a>
{{/if}}
我是把手的新手,即使阅读了一些教程,我仍然不了解这种绑定是如何发生的。我在app.js
函数signIncomplete()
中找到了以下行,
const user = await graph.getUserDetails(accesstoken);
其中getUserDetails()
函数创建如下的user
对象:
const user = await client.api('/me').get();
函数signInComplete()
访问user.mail
和user.userPrincipalName
,但是没有显式代码将此变量暴露在函数外部。然而,在渲染车把模板时以某种方式绑定了变量。我在调试器中检查了user
变量,所以我知道视图中的数据一定是来自signInComplete()
的。我已阅读的一些把手参考资料显示了如何将对象绑定到已编译的模板,但这不是这里所发生的。
此绑定如何完成?正如我提到的,我是手把手的新手,因此,如果这是一种特殊情况或功能,我将不知道它叫什么或如何搜索。因此,链接到文档将不胜感激。
解决方法
绑定发生在您链接到的教程源代码中的line 162 of app.js上。代码是:
app.use(function(req,res,next) {
// Set the authenticated user in the
// template locals
if (req.user) {
res.locals.user = req.user.profile;
}
next();
});
要了解这里发生的情况,我们必须介绍一些内容。
首先,Passport JS用于身份验证。 Passport JS是用于Node应用程序的身份验证中间件。基本上,Passport根据请求对象中的某些数据对用户进行身份验证。如果请求可以通过身份验证,则Passport会将经过身份验证的用户数据添加为请求(user
)对象上的req
属性,供后续处理程序使用。
在上面的代码中,我们可以看到Passport添加的req.user
值正在被访问并分配给res.locals.user
。 res.locals
是Express应用程序中的一个对象,它允许将每个请求的数据附加到响应(res
)对象上。
hbs是本教程中使用的Express的Handlebars视图引擎。绑定值res.locals
的hbs中间件,以便Handlebars模板可以访问它们。