【问题标题】:Meteor + Iron Router to create breadcrumbsMeteor + Iron Router 创建面包屑
【发布时间】:2025-12-29 12:00:12
【问题描述】:

好的,所以我找到了这个帖子:Meteor breadcrumb

但是假设我有以下内容:

<template name="somePage">
    <h1>Page Title</h1>
    {{> breadcrumb}}
</template>

<template name="breadcrumb">
    <ul class="breadcrumb">
        <li>
            <a href="{{pathFor 'homeTemplate'}}">Home</a>
        </li>
        {{#each path}}
        <li>
            <a href="needthepath">{{this}}</a>
        </li>
    </ul>
</template>

Helper:

Template.breadcrumb.helpers({
    path: function() {
        return Router.current().path.split( "/" );
    }
});

好的,所以顶部的链接问题让我了解了基础知识。我试图了解如何在这里做一些应该很明显的事情。我要第一个

  • 为首页,从路径返回的结果:function()开头包含一个空的“”、“page”、“page”等。

    我希望能够合并正确的路径。明确地说,我很想把它完成:

    <template name="breadcrumb">
        <ul class="breadcrumb">
            <li>
                <a href="{{pathFor 'homeTemplate'}}">Home</a>
            </li>
            ~ pseudo logic
            {{#each path that isn't current page}}
            <li>
                <a href="{{dynamicPath}}">{{this}}</a>
            </li>
            {{/each}}
            <li>
                {{ currentPage }}
            </li>
        </ul>
    </template>
    

    有没有人这样做或找到我还没有偶然发现的参考资料?

  • 【问题讨论】:

      标签: meteor iron-router


      【解决方案1】:

      我会用iron:router给你我自己的面包屑食谱。

      它的工作原理是为您的路线提供额外的选项,以便在它们之间建立一个具有父子关系的层次结构。然后我们在路由器上定义一个助手,为我们提供当前路由的父路由列表(到 home)。当您拥有此路线名称列表时,您可以遍历它们以创建您的面包屑。

      首先,我们需要定义我们的面包屑模板,它实际上与您的伪代码非常相似。我正在使用 bootstrap 和 font-awesome,以及一些新引入的 iron:router@1.0.0-pre 功能。

      <template name="breadcrumbs">
          <ol class="breadcrumb">
              <li>
                  {{#linkTo route="home"}}
                      <i class="fa fa-lg fa-fw fa-home"></i>
                  {{/linkTo}}
              </li>
              {{#each intermediateRoutes}}
                  <li>
                      {{#linkTo route=name}}
                          <strong>{{label}}</strong>
                      {{/linkTo}}
                  </li>
              {{/each}}
              <li class="active">
                  <strong>{{currentRouteLabel}}</strong>
              </li>
          </ol>
      </template>
      

      {{#linkTo}} 块助手是iron:router@1.0.0-pre 中的新功能,它只是输出一个带有href 属性的锚标记,其值为{{pathFor "route"}}

      让我们从面包屑模板定义助手:

      Template.breadcrumbs.helpers({
          intermediateRoutes: function() {
              if (!Router.current()) {
                  return;
              }
              // get rid of both the first item, which is always assumed to be "home",
              // and the last item which we won't display as a link
              var routes = Router.parentRoutes().slice(1, -1);
              return _.map(routes, function(route) {
                  // extract name and label properties from the route
                  return {
                      name: route.getName(),
                      label: route.options.label
                  };
              });
          },
          currentRouteLabel: function() {
              // return the label property from the current route options
              return Router.current() && Router.current().route.options.label;
          }
      });
      

      请注意,我们依赖于一个名为“标签”的特殊选项的存在,它表示我们将要放入锚点中的内容,我们也可以使用该名称进行测试。

      parentRoutes 方法是我们需要扩展 Router 的东西:

      _.extend(Router, {
        parentRoutes: function() {
          if (!this.current()) {
            return;
          }
          var routes = [];
          for (var route = this.current().route; !_.isUndefined(route); route = this.routes[route.options.parent]) {
            routes.push(route);
          }
          return routes.reverse();
        }
      });
      

      同样,这个函数假设每个路由(除了“home”)都有一个父属性,其中包含其父路由的名称,然后我们迭代遍历路由层次结构(想象一棵树,就像一个文件系统结构)从当前路由到根路由,将每个中间路由与当前路由一起收集到一个数组中。

      最后,不要忘记使用我们的代码所依赖的两个附加属性声明您的路由,以及一个现在必须的名称,因为路由在 Router.routes 属性中按名称索引:

      Router.route("/", {
        name: "home"
      });
      Router.route("/nested1", {
        name: "nested1",
        parent: "home"
      });
      Router.route("/nested1/nested2", {
        name: "nested2",
        parent: "nested1"
      });
      // etc...
      

      这个示例非常基础,当然不会涵盖所有用例,但应该可以让您在实现自己的面包屑的设计逻辑方面有一个坚实的开端。

      【讨论】:

      • 感谢您提供这个详细的示例!由于必须升级到预发布版本,我目前正被铁路由器错误所困扰……所以整理我的整个应用程序以解决所有问题。
      • 我测试了这个 sn-p 但不幸的是它不适用于我的Meteor &gt;1.0
      • 一切正常,但我在传递 parent_id 相对于 parent: "nested1" 的参数时遇到问题
      【解决方案2】:

      受@saimeunt 的启发,我创建了一个流星面包屑插件,可以在这里找到:https://atmospherejs.com/monbro/iron-router-breadcrumb。您还可以指定父路由和路由本身的标题。

      【讨论】:

        【解决方案3】:

        我使用了 saimeunt 答案,但不得不对模板和模板助手进行小幅更改,因为我的一些路由路径中有参数。这是我的更改。

        模板更改:为中间路由添加 data=getParameter 到 #linkTo

        <template name="breadcrumbs">
            <ol class="breadcrumb">
                <li>
                    {{#linkTo route="dashboard"}}
                        <i class="fa fa-lg fa-fw fa-home"></i>
                    {{/linkTo}}
                </li>
                {{#each intermediateRoutes}}
                    <li>
                        {{#linkTo route=name data=getParameters}}
                            <strong>{{label}}</strong>
                        {{/linkTo}}
                    </li>
                {{/each}}
                <li class='active'>
                    <strong>{{currentRouteLabel}}</strong>
                </li>
            </ol>
        </template>
        

        模板助手更改:添加助手函数 getParameters 以从当前路由获取参数。

        Template.breadcrumbs.helpers({
            intermediateRoutes: function () {
                if (!Router.current()) {
                    return;
                }
                var parentRoutes = Router.parentRoutes();
                var routes = parentRoutes.slice(1, -1);
                var intermediateRoutes = _.map(routes, function (route) {
                    return {
                        name: route.getName(),
                        label: route.options.label
                    };
                });
                return intermediateRoutes;
            },
            currentRouteLabel: function () {
                var currentRouteLabel = Router.current() && Router.current().route.options.label;
                return currentRouteLabel;
            },
            getParameters: function(){
                var currentRoute = Router.current();
                var parameters = currentRoute.params;
                return parameters;
            }
        });
        

        【讨论】:

        • 我必须在路由器Router.route("/", { name: "home", label: 'home', });中包含以下内容