【问题标题】:Get current route name in Ember在 Ember 中获取当前路线名称
【发布时间】:2013-08-20 13:56:09
【问题描述】:

我需要在我的 ember 应用程序中获取当前路由名称;我试过这个: Ember App.Router.router.currentState undefined 但它对我不起作用(我可能会错过一些东西......)我使用 Ember rc6 并且我有一个多语言应用程序;在 applicationRoute 我检测浏览器的语言并重定向到正确的页面:

this.transitionTo(userLang);

但我希望仅当用户在主页上时才执行此操作,因此如下所示:

if (currentRoute == 'home'){
  this.transitionTo(userLang)
}

【问题讨论】:

标签: ember.js


【解决方案1】:

注意:从 Ember 3.16 开始,不仅建议使用原始答案,而且强烈反对观察者。

要获取当前路由名称,您可以使用路由器服务:https://api.emberjs.com/ember/3.18/classes/RouterService/properties/currentRouteName?anchor=currentRouteName

export default class MyComponent extends Component {
  @service router;

  get activeRoute() {
    return this.router.currentRouteName;
  }
}

原答案如下


您可以观察applicationcurrentPath,并在它发生变化时将其设置为当前路线:

App = Ember.Application.create({
  currentPath: '',
});

App.ApplicationController = Ember.Controller.extend({
  updateCurrentPath: function() {
    App.set('currentPath', this.get('currentPath'));
  }.observes('currentPath')
}),

这样您就可以随时使用App.get('currentPath'); 访问currentPath

例如

if (App.get('currentPath') == 'home'){
  this.transitionTo(userLang);
}

希望对你有帮助。

【讨论】:

  • 好吧,如果我在控制器内部执行 'console.log(App.get("currentPath"))',我可以看到它有效;但我需要从ApplicationRoute的redirect方法内部访问currentPath,在这里它不起作用(这里的控制台日志显示currentPath没有值)......可能currentPath只有在调用redirect方法后才会更新.. .
  • 也从控制器做所有事情(所以现在我不再需要 ApplicationRoute 的重定向方法了);感谢您的帮助...
  • 我正在尝试在 Ember App Kit 中执行此操作,其中“App”全局命名空间已替换为 ES6 模块转译器。由于 App.set 和 App.get 不起作用,我如何访问“currentPath”?谢谢!
  • @intuitivepixel ,谢谢,但我观察到参数有问题。例如如果我有:'this.resource('detail', { path: '/detail/:type' }, function() {});' currentPath 是 datail.index。我需要知道类型。你能帮帮我吗?
【解决方案2】:

Ember 自 2.15 起拥有RouterService。它提供当前路由的名称为currentRouteName property。如果您仍在使用这么旧的版本,则 Ember 2.4 - 2.14 存在 polyfill

import Component from '@ember/component';

export default Component.extend({
  router: service(),

  isHomeRoute: computed('router.currentRouteName', function() {
    return this.router.currentRouteName === 'home';
  }),
});

此处提到的所有其他解决方案都依赖于可能已被弃用/删除的私有 API。使用RouterService 至少可以在当前版本上运行,在撰写本文时为3.12

请注意"home" 不是/。根 URL 称为 "index"

【讨论】:

    【解决方案3】:

    这在 1.3.0-beta 上对我有用(快速浏览 1.1.2 的源代码表明它也可以在那里工作):

    App.__container__.lookup('router:main').location.lastSetURL
    

    请注意,文档说明:

    目前,它依赖于浏览器中存在的 hashchange 事件。

    但是,我认为强烈建议不要在生产代码中使用App.__container__。更可接受的替代方法是使用 App.Router.router.currentHandlerInfos,它提供有关当前 Ember 路由的信息。

    另一个选项是ApplicationController 上的currentRouteName。您可以将needs: ['application'] 添加到您的控制器,然后使用controllers.application.currentRouteName 访问路由名称。这将返回类似posts.index 的内容。

    【讨论】:

    • 我可以确认它适用于 1.2.0。但是你必须小心,在应用程序初始加载后它不起作用,即使它是一个深层链接;只有在进行转换后,它才会返回正确的值。
    • App.Router.router.currentHandlerInfos 不仅包含有关当前 Ember 路由的信息,包括其上下文(阅读:模型),它还包含所有父路由的类似信息。如果您需要这些数据,这确实是您的必经之路!
    • App.__container__.lookup() 非常有用。
    【解决方案4】:

    如果您想在组件或控制器中获取当前路由,您可以注入路由服务 (routing: Ember.inject.service('-routing'))

    (对于more)并使用:

    this.get('routing.currentRouteName')this.get('routing.currentPath')

    组件示例和计算属性:

    import Ember from 'ember';
    
    export default Ember.Component.extend({
      routing: Ember.inject.service('-routing'),
    
      checkMyRouteName: Ember.computed('routing.currentRouteName',  function() {
        return this.get('routing.currentRouteName');
      })
    })
    

    控制器示例和计算属性:

    import Ember from 'ember';
    
    export default Ember.Controller.extend({
      routing: Ember.inject.service('-routing'),
    
      checkMyRouteName: Ember.computed('routing.currentRouteName', function() {
        return this.get('routing.currentRouteName');
      })
    })
    

    您的路线中的当前路线您只需要this.routeName

    以路线为例

    import Ember from 'ember';
    
    export default Ember.Route.extend({
      checkMyRouteName() {
        return this.routeName;
      }
    })
    

    【讨论】:

    • 您不应再使用私人-routing 服务。在 Ember 2.15 中添加了一个公共 RouterService,并为 Ember >= 2.4 进行了填充。
    • @jelhan 是的,你是对的。我没有更新它。例如,现在我使用的是 3.8 版本,并且有: import { inject as service } from '@ember/service'; router: service(), get(this, 'router.currentRouteName') 今天我知道我在 StackOverflow 上回复时必须写我参考的版本,因为我什至不记得我写它时是哪个版本:)
    【解决方案5】:

    Ember 命名空间 API 现在有一个 getOwner 方法,这对于查找 currentRouteName 或其他路由属性非常有用。

      const owner        = Ember.getOwner(this);
      const currentRoute = owner.lookup('router:main').currentRouteName;
      const routeInfo    = owner.lookup(`route:${currentRoute}`).get('info');
      // etc.
    

    我创建了一个Ember Twiddle 示例来演示。使用“输出”窗格上方的文本输入来点击其他路由,例如 /blue/green/red

    【讨论】:

    • 请注意EmberRoutercurrentRouteName 属性不仅是私有的,甚至是undocumented。您应该改用 public RouterService,它是在 Ember 2.15 中添加的,并且针对 Ember >= 2.4 进行了填充。
    【解决方案6】:

    我有一段时间遇到同样的问题。然后我开始探索路由器。它总是有一个状态对象,可以使用

    从任何路由获取
    var route = this;
    var handlerInfos = route.get("router.router.state.handlerInfos");
    var currRouteHandlerInfo = handlerInfos[handlerInfos.length-1];
    var currRouteName = currRouteHandlerInfo.name; //"home"
    

    就是这样。现在您有了当前的路线名称!

    如果你想要当前的路由参数,

    var routerParams = this.get("router.router.state.params");
    var currRouteParams = routerParams[currRouteName]; //{ homeId : "1" }
    

    【讨论】:

      【解决方案7】:

      随着向组件的转变,获得路线名称变得更加困难。最好的方法是添加一个初始化器,例如

      ember g initializer router
      

      (从命令行)和

      export function initialize(application) {
        application.inject('route', 'router', 'router:main');
        application.inject('component', 'router', 'router:main');
      }
      
      export default {
        name: 'router',
        initialize
      };
      

      在初始化程序/router.js 中。如果需要,您也可以注入控制器。那就干脆做吧

      this.get('router.currentRouteName');
      

      在 JS 中,或者

      {{router.currentRouteName}}
      

      在模板中。

      这是我发现在 Ember 2.4 中可靠且可观察到的唯一方法

      【讨论】:

      • 非常好,先生
      • 这在 Ember 2.7 中对我有用,非常感谢!这也有助于了解正在发生的事情 - 特别是关于观察路线变化的最后一个答案:discuss.emberjs.com/t/ember-get-current-route-name/10324/7
      • 我使用此信息来帮助构建此组件:stackoverflow.com/questions/39395911/…
      • 在现代 ember 中默认注入服务被认为是一种不好的做法。您应该定义一个服务并在需要的地方注入它。 EmberRouter 甚至不是一项服务,只是在这里用作一项服务。我强烈建议改用在 Ember 2.15 中添加的RouterService
      【解决方案8】:

      您可以简单地解析当前 URL。这样您就可以使用完整的网址,例如:

      http://127.0.0.1:8000/index.html/#/home
      

      并从该字符串中提取后缀:

      /home
      

      这是当前的路线名称。

      一个简单的 JS 函数(不管你的 Ember 版本如何)将是:

      function getCurrentRoute()
      {
          var currentRoute;
          var currentUrl = window.location.href; // 'http://127.0.0.1:8000/index.html/#/home'
      
          var indexOfHash = currentUrl.indexOf('#');
          if ((indexOfHash == -1) ||
              (indexOfHash == currentUrl.length - 1))
          {
              currentRoute = '/';
          }
          else
          {
              currentRoute = currentUrl.slice(indexOfHash + 1); // '/home'
          }
      
          return currentRoute;
      }
      

      使用示例:

      if (getCurrentRoute() == '/home')
      {
      // ...
      }
      

      【讨论】:

        【解决方案9】:

        作为一个更新,在 Ember 1.8.1 中,我们可以通过 this.routeName 获取 Ember.Route 对象中的 routeName。

        【讨论】:

        • 如何在集成测试中获得它? currentRouteName 未定义
        • this.routeName 从应用程序路由调用时返回“应用程序”,不是很有用......类似 route.sub.sub 的东西会很棒。
        【解决方案10】:

        目前从 Ember 1.7.0 开始,您可以通过调用 this.routeName 从路由中获取当前路由。

        【讨论】:

          猜你喜欢
          • 2015-09-14
          • 2020-04-02
          • 2020-04-19
          • 2021-02-16
          • 1970-01-01
          • 2015-07-14
          • 2015-03-29
          • 2016-05-08
          • 1970-01-01
          相关资源
          最近更新 更多