在Ember中获取当前路由名称

17
我需要在我的Ember应用程序中获取当前路由名称;我尝试过这个方法:Ember App.Router.router.currentState undefined,但它对我不起作用(可能是我漏掉了什么...)。我使用的是Ember rc6版本,并且我有一个多语言应用程序;在applicationRoute中,我检测浏览器的语言,并使用以下代码将其重定向到正确的页面:this.transitionTo(userLang); 但我希望仅当用户在首页时才执行此操作,因此类似以下的代码:
if (currentRoute == 'home'){
  this.transitionTo(userLang)
}

11个回答

26

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

要获取当前路由名称,您可以利用Router Service: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;
  }
}

当应用程序的当前路径发生变化时,您可以观察应用程序的currentPath并将其设置为当前路由:
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的重定向方法中访问currentPath,在这里它不起作用(控制台日志显示currentPath没有值)... 可能只有在调用重定向方法后才会更新currentPath... - Cereal Killer
现在从控制器中执行所有操作都可以了(所以我不再需要ApplicationRoute的重定向方法了);感谢您的帮助... - Cereal Killer
4
我会尝试在Ember应用工具包中完成这个操作,这里已将'App'全局命名空间替换为ES6模块转换器。由于无法使用App.set和App.get,我该如何访问'currentPath'呢?谢谢! - Chris
@intuitivepixel,谢谢你。但是我发现params存在问题。例如,如果我有:'this.resource('detail', { path: '/detail/:type' }, function() {});',当前路径是datail.index。我需要知道类型。你能帮我吗? - vicenrele

26

这在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版本兼容。但是你必须小心,它在应用程序的初始加载后不起作用,即使是深度链接;只有在进行转换后,它才会返回正确的值。 - vanthome
7
App.Router.router.currentHandlerInfos 不仅包含有关当前Ember路由及其上下文(即:模型)的信息,还包括所有父级路由的类似信息。如果需要这些数据,那么这确实是一种可行的方法! - nickiaconis
App.__container__.lookup() 非常有用。 - datchung

18

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

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
};

在initializers/router.js中,您也可以将其注入到控制器中(如果需要)。然后只需简单地执行

this.get('router.currentRouteName');
在JS中,或者
{{router.currentRouteName}}

在模板中。

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


1
确实非常好,先生。 - Nicolai Dahl
这在Ember 2.7中对我有用,非常感谢!这也有助于理解正在发生的事情-特别是关于观察路由变化的最后一个答案:http://discuss.emberjs.com/t/ember-get-current-route-name/10324/7 - rmcsharry
我使用了这个信息来帮助构建这个组件:http://stackoverflow.com/questions/39395911/emberjs-2-7-how-to-bind-attribute-disabled-for-a-button/39396958#39396958 - rmcsharry
默认情况下注入服务在现代Ember中被认为是一种不好的做法。您应该定义一个服务并在需要时注入它。EmberRouter甚至不是一个服务,只是在这里被用作一个。我强烈建议使用在Ember 2.15中添加的RouterService - jelhan

18

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

(有关更多信息),然后使用:

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');
  })
})

使用控制器(Controller)和计算属性(Computed Property)的示例:

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;
  }
})

1
你不应再使用私有的 -routing 服务。在 Ember 2.15 中已经添加了公共的 RouterService,并且对于 Ember >= 2.4 进行了 polyfill。 - jelhan
@jelhan 是的,你说得对。我没有更新它。例如,现在我正在使用3.8版本,有:import { inject as service } from '@ember/service';router: service(),get(this, 'router.currentRouteName')今天我学到了当我在StackOverflow上回复时必须写明我所参考的版本,因为我甚至不记得我写它时是哪个版本 :) - Hubert Olender

13

更新一下,在Ember 1.8.1中,我们可以通过 this.routeName 在Ember.Route对象内获取路由名称。


如何在集成测试中获取它?currentRouteName未定义。 - SuperUberDuper
2
当从应用程序路由调用时,this.routeName返回“application”,并不是很有用...如果能像route.sub.sub这样就好了。 - Jan Werkhoven

3

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


1
请注意,EmberRoutercurrentRouteName属性不仅是私有的,甚至未记录在文档中。您应该使用公共的RouterService,它在Ember 2.15中添加,并且对于Ember >= 2.4进行了填充。 - jelhan

3

截至目前,Ember 1.7.0版本中,您可以通过调用this.routeName在当前路由中获取当前路由。


2
Ember自2.15版本起拥有一个RouterService。它提供了当前路由的名称,即currentRouteName属性。如果您仍在使用旧版本(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"

0

我曾经有同样的问题。后来我开始探索路由器。它总是有一个状态对象,可以从任何路由中获取。

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" }

0
这对我在route.js文件上起作用: this.controller.target.currentPath

您的回答可以通过提供更多支持性信息而得到改善。请[编辑]以添加进一步的细节,例如引用或文档,以便他人可以确认您的回答是否正确。您可以在帮助中心找到关于如何撰写好的回答的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接