在 Express/Jade 视图中访问当前请求
Posted
技术标签:
【中文标题】在 Express/Jade 视图中访问当前请求【英文标题】:Access current request in Express/Jade view 【发布时间】:2012-09-25 22:29:03 【问题描述】:我有一个布局 Jade 视图,它有一个通过无序列表提供的菜单,我想在浏览器中呈现当前页面时将 <li>
设置为 <li class="active">...</li>
。
我假设我必须访问当前请求以确定何时在 <li>
上设置属性
我找不到任何有关如何执行此操作的示例,因此希望有人可以提供帮助
谢谢
【问题讨论】:
【参考方案1】:在你的路由中调用 res.render() 之前试试这个:
res.locals.path = req.path;
res.render('/page');
或
res.render('/page', path: req.path );
那么您将不得不在您的视图中执行一堆 if/else 语句(如上述解决方案所建议的那样)。
- if(currentUrl === '/')
li(class='active')
a(href='/') Current Driver Standings
- else
li
a(href='/') Current Driver Standings
但是,我更喜欢在客户端执行此操作,以使我的模板文件尽可能多地避免逻辑:
在页面模板文件中(这是ejs,不知道如何在jade中回显):
<body data-path="<%= path %>">
然后使用 jQuery,您可以从 body 中获取路径并附加一个活动类:
$(function()
var path = $('body').attr('data-path');
$('nav li a[href='+path+']').parents('li').addClass('active');
);
更新:您也可以只使用var path = window.location.pathname
而不是将其保存到body
上的属性中
//no need to save path to <body> tag first:
$(function()
var path = window.location.pathname;
$('nav li a[href='+path+']').parents('li').addClass('active');
);
【讨论】:
我唯一要说的是,你依赖于拥有 JS 的用户(这几天不是一个大问题),但由于某种原因你可能最终会以属性的形式存在其他东西,并且产生了很多丑陋的标记 您的示例中还有错字吗? req.path 在 EJS 中可用吗?它不应该是您的视图模型的属性吗? 抱歉,在我的路线中,我执行 res.locals.req = req 所以我可以访问所有这些信息。但我刚刚意识到你也可以只使用 window.location.pathname 而不是将其保存在 body 标签上。 哦,是的!非常感谢 :) 你有本地人的链接吗? 您还可以将 app.locals 用于要向所有模板公开的全局内容。 res.locals 仅用于路线。【参考方案2】:这是一种更简洁的方法,服务器端:
在您的routes.js
(或任何地方)中定义一个代表您的导航的对象数组,如下所示:
var navLinks = [
label: 'Home', key: 'home', path: '' ,
label: 'About', key: 'about', path: '/about' ,
label: 'Contact', key: 'contact', path: '/contact'
]
将navLinks
变量传递给您的视图,以及您想要突出显示的项目的键:
res.render('home', title: 'Welcome!', section: 'home', navLinks: navLinks );
您还可以将navLinks
变量添加到app.locals
,这样您就不必始终将其显式提供给视图。
然后在您的翡翠模板中循环遍历链接数组并将活动类设置在其键与提供的部分匹配的类上:
ul(class='nav nav-list')
- navLinks.forEach(function(link)
- var isActive = (link.key == section ? 'active' : '')
li(class=isActive)
a(href=link.path)= link.label
- )
【讨论】:
不错的一个。自从它发布以来已经有一段时间了,但它仍然是一个好主意。我还是 Pug 模板的新手,所以现在我只是将另一个字符串连接到 isActive,因为我使用的是 Bootstrap 导航栏。【参考方案3】:在你的路由文件中传递 req.originalUrl。示例:在您的 /routes/about.js
router.get('/', function(req, res)
res.render('about',
url: req.originalUrl
);
);
然后,在你的玉模板上写下 if else 条件
if(url==='/about-us')
li(class='active')
a(href='about-us') About Us
else
li
a(href='about-us') About Us
【讨论】:
【参考方案4】:您可以在 app.js 中使用全局变量,例如:
// Global vars
app.use( function ( req, res, next )
// rest of your code ...
res.locals.current_url = req.path;
// rest of your code ...
next();
);
// then in your .jade file:
ul.navbar-nav.mr-auto
li(class="nav-item # current_url === '/page1' ? 'active' : ''")
a.nav-link(href='/page1') Page1
这样你就可以在你的视图文件中全局使用“current_url”
【讨论】:
【参考方案5】:我想出了这个可行的方法,但我不确定它是否是最佳实践。无论哪种方式,请告诉我:
response.render("current/currentSchedule",
title: "Current Race Schedule",
currentUrl: req.path,
);
ul(class='nav nav-list')
li(class='nav-header') Current Season
- if(currentUrl === '/')
li(class='active')
a(href='/') Current Driver Standings
- else
li
a(href='/') Current Driver Standings
- if(currentUrl === '/constructor-standings')
li(class='active')
a(href='/constructor-standings') Current Constructor Standings
- else
li
a(href='/constructor-standings') Current Constructor Standings
- if(currentUrl === '/current-schedule')
li(class='active')
a(href='/current-schedule') Current Race Schedule
- else
li
a(href='/current-schedule') Current Race Schedule
【讨论】:
这很难维护,因为你要多次重复类名和链接,而且代码也很多。请参阅我的答案以获得更简单的方法。它也可以适应您的答案中的 currentUrl ,但通常主要导航项目应保持突出显示子路径,这不会发生在您使用的方法中。以上是关于在 Express/Jade 视图中访问当前请求的主要内容,如果未能解决你的问题,请参考以下文章
如何正确渲染部分视图,并使用 Express/Jade 在 AJAX 中加载 JavaScript 文件?
webstorm创建nodejs + express + jade 的web 项目
Heroku(Cedar) + Node + Express + Jade 子目录中的客户端 javascript 文件在本地与 foreman+curl 一起工作,但在推送到 Heroku 时不能