【问题标题】:Finding current url inside EJS view when using express使用 express 时在 EJS 视图中查找当前 url
【发布时间】:2013-09-01 07:45:58
【问题描述】:

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

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

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

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

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

有没有办法从 EJS 代码中找到我当前的路径/url?

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

【问题讨论】:

    标签: javascript node.js express ejs


    【解决方案1】:

    据我所知,除非您在内部修改 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>
      <% } %>
    <% }) %>
    

    【讨论】:

    • 简单的解决方案,但您不能在导航对象上创建forEach,除非您将其包装在例如Object.keys(nav)
    【解决方案2】:

    在我使用过的几乎所有节点/express 模板语言(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 中获得活跃?
    • @TravelingTechGuy,我不能谈论 EJS,但我正在使用 Jade,并且像上面一样在中间件中设置 active,将其传递给视图,你会像这样引用它一个普通变量li.nav-item(class=(active === 'home') ? 'active' : undefined) 我很欣赏这种方法@tandrewnichols,今天仍然适用。
    【解决方案3】:

    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 )
    
    } )
    

    menu.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>
    
            <% } %>
        <% } %>
    

    【讨论】:

      猜你喜欢
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 2016-10-06
      • 2015-09-10
      • 2011-06-25
      • 2011-08-15
      相关资源
      最近更新 更多