Javascript 使用express时在EJS视图中查找当前url
我正在使用Express和EJS提供页面服务。我正在为UI使用引导,特别是导航栏 我想在当前页面的Javascript 使用express时在EJS视图中查找当前url,javascript,node.js,express,ejs,Javascript,Node.js,Express,Ejs,我正在使用Express和EJS提供页面服务。我正在为UI使用引导,特别是导航栏 我想在当前页面的项中添加一个'active'类,以显示当前页面。但是,我找不到如何从呈现页面的EJS代码中获取URL 我找到了两种解决方法:我使用include将页面名作为参数传递到路由的res.render('myview',{pageName:'myview'})-不可扩展,可能会导致问题 另一种方法是在客户端使用jQuery在页面准备就绪时将'active'类添加到项目中,但这意味着在每个视图中包含这段脚本+
项中添加一个'active'
类,以显示当前页面。但是,我找不到如何从呈现页面的EJS代码中获取URL
我找到了两种解决方法:我使用include将页面名作为参数传递到路由的res.render('myview',{pageName:'myview'})代码>-不可扩展,可能会导致问题
另一种方法是在客户端使用jQuery在页面准备就绪时将'active'
类添加到项目中,但这意味着在每个视图中包含这段脚本+一些无用的客户端循环
以前使用过几种服务器端渲染语言,我觉得我遗漏了一些东西。在线EJS文档也不是很好
有没有办法从EJS代码中找到我当前的路径/url
更新:
我采纳了前两个建议,并将视图名称作为参数传递给视图。我真的很喜欢@tandrewnichols自动计算它的想法,但最终,复制粘贴字符串更容易:)在我使用的几乎所有节点/表达式模板语言(ejs、kiwi、swig、jade)中,答案都是否定的。我总是设置一个名为“active”的变量,然后检查它。正如您所说,这不是一个很好的答案,尽管我不知道可伸缩性是个问题。如果每个url都呈现自己的视图(或者即使您有一个用于视图呈现的公共处理程序),那么像req.active=“Somepage”
这样的说法应该不会太难。另一种可能是添加基于路由的中间件。差不多
app.use(function(req, res, next){
req.active = req.path.split('/')[1] // [0] will be empty since routes start with '/'
next();
});
然后,您只需确保具有相应导航组件的任何路由使用唯一路径,如
app.get('/students', ....)
app.get('/classes', ....)
app.get('/teachers', ....)
// etc.
编辑:为了回应您的评论,我总是将所有视图内容放入req
中的一个对象键中,并且通常根据我使用的模板命名键。因此,我可能会使用上面的示例来设置req.ejs.active
,然后
res.render('myview', req.ejs);
这种方法使得将逻辑分离为多个中间件函数变得更加容易,并且不必将一个巨大的匿名对象传递给res.render。据我所知,除非您在内部修改EJS,否则您无法执行您所要求的操作。然而,一个不那么麻烦的解决方案是在每次页面调用时传递请求的URL属性,而不是在每个路由上定义它
app.get('/url', function (req, res) {
res.render('view', {
page: req.url,
nav: {
'Page 1': '/page1',
'Page 2': '/page2',
'Page 3': '/page3'
}
});
});
如果您只想获取URL的第一部分并匹配它,那么您可以在req.URL
上调用split('/')
。然后,可以在模板文件中放置一个循环,为导航栏创建列表
<% nav.forEach(function(title) { %>
<% if (nav[title] == page) { %>
<li class="active">This part of the navigation bar is active.</li>
<% } else { %>
<li>This part of the navigation bar is normal.</li>
<% } %>
<% }) %>
导航栏的此部分处于活动状态
导航栏的这一部分是正常的
index.js
/* object menu */
const menu = [
{
name: 'Home',
url: '/'
},
{
name: 'About',
url: '/about'
}
]
/* route */
app.get( '/', function( request, response) {
let data = {
title: 'Home',
url: request.url,
menu: menu
}
response.render( 'home', data )
} )
app.get( '/about', function( request, response) {
let data = {
title: 'About',
url: request.url,
menu: menu
}
response.render( 'about', data )
} )
<% for ( let i in menu ) { %> // loop menu
<% if ( menu[i].url == url ) { %> // match, add active in class
<a class="active" href="<%= menu[i].url %>" ><%= menu[i].name %></a>
<% } else { %>
<a class="" href="<%= menu[i].url %>" ><%= menu[i].name %></a>
<% } %>
<% } %>
menu.js
/* object menu */
const menu = [
{
name: 'Home',
url: '/'
},
{
name: 'About',
url: '/about'
}
]
/* route */
app.get( '/', function( request, response) {
let data = {
title: 'Home',
url: request.url,
menu: menu
}
response.render( 'home', data )
} )
app.get( '/about', function( request, response) {
let data = {
title: 'About',
url: request.url,
menu: menu
}
response.render( 'about', data )
} )
<% for ( let i in menu ) { %> // loop menu
<% if ( menu[i].url == url ) { %> // match, add active in class
<a class="active" href="<%= menu[i].url %>" ><%= menu[i].name %></a>
<% } else { %>
<a class="" href="<%= menu[i].url %>" ><%= menu[i].name %></a>
<% } %>
<% } %>
//循环菜单
//匹配,在类中添加活动
如何从EJS进入活动状态?@TravelingTechGuy,我不能谈论EJS,但我使用jade,在上面的中间件中设置active
,将其传递给视图,您可以像引用普通变量一样引用它li.nav项(class=(active=='home')?“active”:未定义)
我很欣赏这种方法@tandrewnichols,它今天仍然适用。简单的解决方案,但是你不能在nav对象上创建一个forEach
,除非你将它包装在例如object.keys(nav)