如何定位 Express 中的当前页面导航?

How can I target the current page navigation in Express?

现在,我正在通过 jQuery 执行此操作,例如:

$(".navigation__item a").each(function () {
  if (window.location.pathname === $(this).attr("href")) {
    $(this).parent().addClass("active");
  }
});

但是,这不是完全可靠的,所以我想将 "active" 参数传递到我的导航视图,但我不确定该怎么做。这是我的导航模板的片段:

<aside class="navigation-wrap">
  <ul class="navigation">
    <li class="navigation__item{{#if current}} active{{/if}}">
      <a href="/admin/dashboard">Overview</a>
    </li>

    <li class="navigation__item{{#if current}} active{{/if}}">
      <a href="/admin/customization">Customization</a>
    </li>

    <li class="navigation__item{{#if current}} active{{/if}}">
      <a href="/admin/employees">Employee</a>
    </li>
  </ul>
</aside>

这是我的路线文件的片段:

app.get("/admin/:directory/:page", require("connect-ensure-login").ensureLoggedIn("/admin"), (req, res) => {
  if (req.params.page === "new") {
    res.render("admin/" + req.params.directory + "/new", Object.assign({ layout: "layouts/admin", navHighlight: "active" }, app.get("result")[0]));
  } else {
    employeeService.find({ query: { Slug: req.params.page }}, (error, employee) => {
      employee = employee[0];

      res.render("admin/employees/employee", Object.assign({ employeeRequest: req.params.page, Title: "Admin | " + employee.Name, layout: "layouts/admin" }, app.get("result")[0]));
    });
  }
});

有人完成过这样的事情吗?我已经搜索过 SO 和其他地方,但没有找到任何东西。

肯定有不同的可能方法。我突然想到的一件事是,您可以将导航保存在一个变量中,例如:

var navi = [
  {url: "/admin/dashboard", name: "Overview"},
  {url: "/admin/customization", name: "Customization"},
  {url: "/admin/employees", name: "Employee"}
];

所以我们有一个对象数组,可以循环动态写入 <li><a> 标签。在条件下,根据请求 URL.

设置 link active 应该也没什么大不了的

通过最少的设置,我能够根据硬编码请求进行输出 URL:

<ul>
    <li class=''><a href='/admin/dashboard'>Overview</a></li>
    <li class=''><a href='/admin/customization'>Customization</a></li>
    <li class='active'><a href='/admin/employees'>Employee</a></li>
</ul>

下面是设置。

index.js:

var express = require('express');
var app = express();
var hbs = require('hbs');

app.set('view engine', 'hbs');

hbs.registerHelper('list', function(naviItems, reqUrlItem, options) {
  var out = "";
  var cssClass = "";

  for(var i=0, l=naviItems.length; i<l; i++) {
    if (reqUrlItem === naviItems[i].url) {
        cssClass = "active";
    }
    out += "<li class='"+cssClass+"'><a href='"+naviItems[i].url+"'>" + naviItems[i].name + "</a></li>";
    cssClass = "";
  }

  return out;
});

var navi = [
  {url: "/admin/dashboard", name: "Overview"},
  {url: "/admin/customization", name: "Customization"},
  {url: "/admin/employees", name: "Employee"}
];
var reqUrl = "/admin/employees";

app.get('/', function(req, res) {
   res.render('test', {navi: navi, reqUrl: reqUrl});
});

app.listen(3000);

test.hbs

<ul>
     {{#list navi reqUrl}}{{/list}}
</ul>

所以基本上你注册了一个名为 list 的 Handlebars 辅助函数,你用你的导航变量和你的请求参数调用它(之前都已经传递给模板)。辅助函数应该是不言自明的。 希望对您有所帮助!

在 Micheal Troger 的帮助下,我想出了一个解决方案。

src/routes/index.js

app.get("/admin/*", require("connect-ensure-login").ensureLoggedIn("/admin"), (req, res) => {
  const parts = req.path.split("/");

  /*
  console.log(
    req.path + "\n",
    "0: " + parts[0] + "\n",  //
    "1: " + parts[1] + "\n",  // admin
    "2: " + parts[2] + "\n",  // employees   // directory
    "3: " + parts[3]          // david-sarif // page
  );
  */

  if (parts[3]) {
    if (parts[3] === "new") {
      res.render("admin/" + parts[2] + "/new", Object.assign({ layout: "layouts/admin", navigation: app.get("navigationAdmin") }));
    } else {
      employeeService.find({ query: { Slug: parts[3] }}, (error, employee) => {
        employee = employee[0];

        res.render("admin/employees/employee", Object.assign({ employeeRequest: parts[3], Title: "Admin | " + employee.Name, layout: "layouts/admin", navigation: app.get("navigationAdmin") }));
      });

      handheldService.find({ query: { Slug: parts[3] }}, (error, handheld) => {
        handheld = handheld[0];

        res.render("admin/handhelds/handheld", Object.assign({ handheldRequest: parts[3], Title: "Admin | " + handheld.Name, layout: "layouts/admin", navigation: app.get("navigationAdmin") }));
      });
    }
  } else {
    res.render("admin/" + req.params[0], Object.assign({ user: req.user, title: "Admin", layout: "layouts/admin", navigation: app.get("navigationAdmin") }));
  }
});

src/middleware/index.js

module.exports = (app) => {
  app.use((req, res, next) => {
    // Create navigation for backend
    function createNavigation(navigation, data) {
      let
        html = "",
        extraClass = "";

      const parts = req.path.split("/");

      /*
      console.log(
        req.path + "\n",
        "0: " + parts[0] + "\n",  //
        "1: " + parts[1] + "\n",  // admin
        "2: " + parts[2] + "\n",  // employees   // directory
        "3: " + parts[3]          // david-sarif // page
      );
      */

      for (data of navigation) {
        if (parts[2] && data.url.includes(parts[2])) {
          extraClass = " active";
        }

        html += "<li class='navigation__item" + extraClass + "'><a href='" + data.url + "'>" + data.name + "</a></li>";
        extraClass = "";
      }

      app.set("navigationAdmin", html);
    }

    const navigationItems = [
      { url: "/admin/dashboard", name: "Overview" },
      { url: "/admin/customization", name: "Customization" },
      { url: "/admin/employees", name: "Employee" },
      { url: "/admin/handhelds", name: "Handheld" }
    ];

    createNavigation(navigationItems);
  });
};

此代码允许我的导航保持突出显示,无论我是在确切的页面还是子页面上。例如,site.com/example 和 site.com/example/new 都会在我的导航中点亮 "Example"。

轰隆隆。

编辑:忘记添加导航实际显示的位置!

<aside class="navigation-wrap">
  <ul class="navigation">
    {{{ navigation }}}
  </ul>
</aside>