我正在尝试在导航栏上呈现用户名,但该导航栏位于部分文件夹中,而node.js中的所有路径都不会渲染navbar.ejs,因为它只是部分。我正在使用ejs-mate库来使用可重用的布局组件来用于其他的html组件,这样我就不需要复制和粘贴代码了(遵循DRY原则),为什么?因为ejs没有内置的可重用布局组件的功能,其他开发人员不维护其他库。
目前
我有两条路线
app.get('/', passport.isAuthenticated, function(req, res) {
res.render('home' {
user: req.user
});
});
app.get('/anotherRoute', function(req, res) {
res.render('test');
});
我有两个ejs文件
home.ejs
<%- layout('boilerplate') %>
<h1>Home Page</h1>
another.ejs
<%- layout('boilerplate') %>
<h1>Another Page</h1>
这两个ejs文件正在使用样板文件。我不会一遍又一遍地复制和粘贴相同的代码。
boilerplate.ejs - 在这个文件中,我包含了navbar和其他一些部分内容。
<!DOCTYPE html>
<html lang="en">
<head>
<% include ./partials/navbar %>
</head>
<body>
<header>
<% include ./partials/header %>
</header>
<div class="container">
<main>
<%- body -%>
</main>
<footer>
<% include ./partials/footer %>
</footer>
</div>
</body>
</html>
这是导航栏文件,并查看导航栏右侧类
if user is logged in render name
else render about and signup
navbar.ejs
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">
StartupClone
</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/">About</a></li>
<% if (!user) { %>
<li><a href="/signup">Signup</a></li>
<li><a href="/login">Login</a></li>
</ul>
<% } else{ %>
<li><a><%= user.profile.name %></a></li>
<% } %>
</div>
</nav>
现在问题是它只使用我传递用户对象但不传递其他路由的路由。我知道我必须将用户的对象传递给每一条路线,但这并不好,因为我必须再次在每条路线中复制并粘贴代码,这违反了DRY原则,
想象一下,如果有40条路线需要使用该导航栏,那对我来说将是一场噩梦:(
如果你们对如何解决这个问题有任何想法,请随时提出如何解决这个问题的想法。
答案 0 :(得分:2)
你有来传递一个具有每个res.render()
电话的已使用属性的对象,但是没有办法解决它。它甚至出现在ejs-mate文档的使用示例中。
话虽如此,有一种方法可以保持代码干净。使用在输入对象上设置共享属性的函数,然后为每个路径集设置它所需的唯一属性:
function setSharedProperties(req, data) {
if(!(data instanceof Object)) {
data = {};
}
data.user = req.user;
return data;
}
app.get('/', passport.isAuthenticated, function(req, res) {
res.render('home', setSharedProperties(req))
});
app.get('/anotherRoute', function(req, res) {
res.render('test', setSharedProperties(req, {prop1: val1}));
});
答案 1 :(得分:1)
必须在视图中传递您尝试访问的对象。 您可以做的一件事是在会话中存储用户对象,并在视图中检查用户对象的会话。 这样你就必须至少传递会话对象,我使用这个技巧来解决这个问题。
在您的中间件passport.isAuthenticated成功登录时保存会话中的用户对象
module.exports.isAuthenticated = function(req, res, next) {
/*
check for valid credentials
*/
if (success)
{
req.session.user = foundUserInfo;
}
next();
}
并在您的局部视图中
<!-- navbar.ejs -->
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">
StartupClone
</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/">About</a></li>
<% if (!session.user) { %>
<li><a href="/signup">Signup</a></li>
<li><a href="/login">Login</a></li>
</ul>
<% } else{ %>
<li><a><%= session.user.profile.name %></a></li>
<% } %>
</div>
现在你只需为每条路线传递会话对象。
app.get('/', passport.isAuthenticated, function(req, res) {
res.render('home' {
user: req.user,
session: req.session
});
});
app.get('/anotherRoute', function(req, res) {
res.render('test', {session: null});
});