6

我正在使用 Express 和 EJS 来提供页面。我正在为 UI 使用 Bootstrap,特别是导航栏。

我想为'active'当前页面的项目添加一个类<li>,以显示当前页面。但是,我找不到如何从呈现页面的 EJS 代码中获取 URL。

我找到了 2 个解决方法:我使用了将页面名称作为参数传递到路由中res.render('myview', {pageName: 'myView'});- 这是不可扩展的,可能会导致问题。

另一种方法是在客户端使用 jQuery'active'在页面准备好时将类添加到项目中 - 但这意味着在每个视图中都包含这段脚本 + 一些无用的客户端循环。

之前使用过几种服务器端渲染语言,我觉得我错过了一些东西。并且在线 EJS 文档也不是很好。

有什么方法可以从 EJS 代码中找到我当前的路径/url?

更新: 我采用了前 2 条建议,并将视图名称作为参数传递给视图。我真的很喜欢@tandrewnichols 自动计算它的想法,但最终,复制粘贴字符串更容易:)

4

3 回答 3

21

据我所知,除非您在内部修改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 的第一部分并匹配它,那么您只需调用split('/'). req.url然后,您可以在模板文件中放置一个循环来为您的导航栏创建列表。

<% 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>
  <% } %>
<% }) %>
于 2013-08-29T03:41:56.117 回答
4

在我使用过的几乎所有节点/表达模板语言(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。

于 2013-08-29T02:47:40.027 回答
2

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 )

} )

菜单.js

    <% 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>

        <% } %>
    <% } %>
于 2019-09-25T09:34:05.170 回答