【问题标题】:Display crumble path with ember用 ember 显示崩溃路径
【发布时间】:2013-02-14 10:08:47
【问题描述】:

我想用 Ember 显示一个崩溃的路径。如何遍历当前路径?

在我看来有两种方法:

余烬之路

编辑:见下面我的回答

我会根据当前显示面包屑的状态更新此问题。您可以浏览此问题的修订版本以查看历史记录。

这里有几个目标:

  1. 监听路线变化
  2. 寻找当前路线
  3. 显示当前路线列表
  4. 显示路线中步骤的工作链接

控制器

App.ApplicationController = Ember.Controller.extend({
    needs: ['breadcrumbs'],
    currentPathDidChange: function() {
        path = this.get('currentPath');
        console.log('path changed to: ', path);
        this.get('controllers.breadcrumbs').set('content',this.get('target.router.currentHandlerInfos'));
    }.observes('currentPath')
});
App.BreadcrumbsController = Em.ArrayController.extend({});

路由器

App.ApplicationRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render();
        this.render('breadcrumbs', {
            outlet: 'breadcrumbs',
            into: 'application',
            controller: this.controllerFor('breadcrumbs')
        });
    }
});

模板

{{! application template }}
<div class="clearfix" id="content">
    {{outlet "breadcrumbs"}}
    {{outlet}}
</div>

{{! breadcrumbs template }}
<ul class="breadcrumb">
  {{#each link in content}}
    <li>
      <a {{bindAttr href="link.name"}}>{{link.name}}</a> <span class="divider">/</span>
    </li>
  {{/each}}
</ul>

目前要解决的问题是:

  • 当我转到 URL:#/websites/8/pages/1 时,面包屑的输出是:(我删除了所有脚本标签占位符
<ul class="breadcrumb">
  <li>
    <a href="application" data-bindattr-34="34">application</a> <span class="divider">/</span></li>
  <li>
    <a href="sites" data-bindattr-35="35">sites</a> <span class="divider">/</span>
  </li>
  <li>
    <a href="site" data-bindattr-36="36">site</a> <span class="divider">/</span>
  </li>
  <li>
    <a href="pages" data-bindattr-37="37">pages</a> <span class="divider">/</span>
  </li>
  <li>
    <a href="page" data-bindattr-38="38">page</a> <span class="divider">/</span>
  </li>
  <li>
    <a href="page.index" data-bindattr-39="39">page.index</a> <span class="divider">/</span>
  </li>
</ul>
  • URL 应该是有效的路由
  • 菜单现在用{{#linkTo}} 硬编码到路线,我试图让它动态化,比如here,但transitionTo 不会触发currentPath-observer

另一种方式

大部分与上述相同,但有一些不同之处。面包屑是通过循环 location.hash 而不是从路由器获取的。

ApplicationController 变为:

ApplicationController = Ember.Controller.extend({
    needs: ['breadcrumbs'],
    hashChangeOccured: function(context) {
        var loc = context.split('/');
        var path = [];
        var prev;
        loc.forEach(function(it) {
            if (typeof prev === 'undefined') prev = it;
            else prev += ('/'+it)
            path.push(Em.Object.create({ href: prev, name: it }));
        });
        this.get('controllers.breadcrumbs').set('content',path)
    }
});
ready : function() {
    $(window).on('hashchange',function() {
        Ember.Instrumentation.instrument("hash.changeOccured", location.hash);
    });
    $(window).trigger('hashchange');
}

我们需要在 ApplicationRoute

中订阅自定义处理程序
App.ApplicationRoute = Ember.Route.extend({
    setupController: function(controller, model) {
        Ember.Instrumentation.subscribe("hash.changeOccured", {
            before: function(name, timestamp, payload) {
                controller.send('hashChangeOccured', payload);
            },
            after: function() {}
        });
    }
});

到目前为止,替代方法对我来说效果最好,但这不是一个好方法,因为当您将路由器配置为使用 history 而不是 location.hash 时,此方法将不再有效。

【问题讨论】:

  • 你能出示你的代码吗?
  • 你试过在路由器中设置变量吗?
  • 我现在将此问题与当前状态保持同步
  • 现在似乎应该在组件中,而不是控制器/视图。

标签: ember.js breadcrumbs ember-router


【解决方案1】:

根据您当前的面包屑输出,我猜您的路由器有错误。

以下命令应返回带有当前面包屑的数组:

App.get('Router.router.currentHandlerInfos');

你的路由器应该是嵌套的:

this.resource('page 1', function () {
    this.resource('page 2');
});

您可以在面包屑中使用#linkTo 代替a 标签,您将免费获得活跃课程。

【讨论】:

    【解决方案2】:

    我想出了一个更简单的解决方案,并发布到Ember discourse

    【讨论】:

      【解决方案3】:

      我找到了一个 (Ember-way) 显示面包屑的解决方案。它基于路由器而不是我的location.hash

      基础设施

      首先,我们需要为面包屑创建基础架构,然后再从面包屑数组中添加或删除项目。

      菜单

      在我的 app.js 中,我定义了一个 NavItem-object。这是所有可导航项目的骨架。我用它来定义我的菜单项,但我们也将它用于面包屑。

      App.NavItem = Em.Object.extend({
          displayText: '',
          routeName: ''
      });
      // define toplevel menu-items
      App.dashboardMenuItem = App.NavItem.create({
          displayText: 'Dashboard',
          routePath: 'dashboard',
          routeName: 'dashboard'
      });
      App.sitesMenuItem = App.NavItem.create({
          displayText: 'Websites',
          routePath: 'sites.index',
          routeName: 'sites'
      });
      

      控制器

      我们需要一个 BreadcrumbsController 将面包屑放在一个中心位置

      App.BreadcrumbsController = Em.ArrayController.extend({
          content: []
      });
      

      我的 ApplicationController 依赖于 BreadcrumbsController

      App.ApplicationController = Ember.Controller.extend({
          needs: ['breadcrumbs']
      });
      

      BreadcrumbsViewApplicationView的子视图

      观看次数

      App.ApplicationView = Ember.View.extend({
          BreadcrumbsView: Ember.View.extend({
              templateName: 'breadcrumbs',
      
              init: function() {
                  this._super();
                  this.set('controller', this.get('parentView.controller.controllers.breadcrumbs'));
              },
              gotoRoute: function(e) {
                  this.get('controller').transitionToRoute(e.routePath);
              },
      
              BreadcrumbItemView: Em.View.extend({
                  templateName:'breadcrumb-item',
                  tagName: 'li'
              })
          })
      });
      

      模板

      在我的 应用程序-模板中,我在出口上方输出面包屑视图

      {{view view.BreadcrumbsView}}
      {{outlet}}
      

      我正在使用 Twitter Bootstrap,所以我的 breadcrumbs-模板的标记是

      <ul class="breadcrumb">
        {{#each item in controller.content}}
            {{view view.BreadcrumbItemView itemBinding="item"}}
        {{/each}}
      </ul>
      

      breadcrumb-item-模板

      <a href="#" {{action gotoRoute item on="click" target="view.parentView"}}>
        {{item.displayText}}
      </a> <span class="divider">/</span>
      

      路由

      我们需要响应应用中的路由来更新面包屑。

      当我的 SitesRoute(或任何其他顶级路由)被激活时,我们将 NavItem 推送到面包屑,但我也想对我的其他顶级路由执行此操作,所以我首先创建TopRoute

      App.TopRoute = Em.Route.extend({
          activate: function() {
              this.controllerFor('menu').setActiveModule(this.get('routeName'));
              var menuItem = app.menuItems.findProperty('routeName',this.get('routeName'));
              this.controllerFor('breadcrumbs').get('content').pushObject(menuItem);
          },
          deactivate: function() {
              var menuItem = app.menuItems.findProperty('routeName',this.get('routeName'));
              this.controllerFor('breadcrumbs').get('content').removeObject(menuItem);
          }
      });
      

      我所有的顶级路由都从这条路由延伸,所以面包屑会自动更新

      App.SitesRoute = App.TopRoute.extend();
      

      对于更深层次,它的工作原理几乎相同,您所要做的就是使用 activatedeactivate 挂钩从面包屑中推送/删除对象

      App.SiteRoute = Em.Route.extend({
          activate: function() {
              var site = this.modelFor('site');
              this.controllerFor('breadcrumbs').get('content').pushObject(app.NavItem.create({
                  displayText: site.get('name'),
                  routePath: 'site',
                  routeName: this.get('routeName')
              }));
          },
          deactivate: function() {
              var site = this.modelFor('site');
              this.controllerFor('breadcrumbs').get('content').removeAt(1);   
          }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-09
        • 2012-10-05
        • 2017-02-12
        • 2015-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多