【问题标题】:Access current request in Express/Jade view在 Express/Jade 视图中访问当前请求
【发布时间】:2012-09-25 22:29:03
【问题描述】:

我有一个布局 Jade 视图,它有一个通过无序列表提供的菜单,我想在浏览器中呈现当前页面时将 <li> 设置为 <li class="active">...</li>

我假设我必须访问当前请求以确定何时在 <li> 上设置属性

我找不到任何有关如何执行此操作的示例,因此希望有人可以提供帮助

谢谢

【问题讨论】:

    标签: node.js express pug


    【解决方案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 ,但通常主要导航项目应保持突出显示子路径,这不会发生在您使用的方法中。
        猜你喜欢
        • 2012-02-26
        • 1970-01-01
        • 1970-01-01
        • 2012-09-23
        • 2015-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多