在 Ember 中获取当前路线名称

Posted

技术标签:

【中文标题】在 Ember 中获取当前路线名称【英文标题】:Get current route name in 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)

【问题讨论】:

Emberjs - How to access the current state or route name in RC1?的可能重复 【参考方案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') 今天我知道我在 *** 上回复时必须写我参考的版本,因为我什至不记得我写它时是哪个版本:) 【参考方案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 我使用此信息来帮助构建此组件:***.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 从路由中获取当前路由。

【讨论】:

以上是关于在 Ember 中获取当前路线名称的主要内容,如果未能解决你的问题,请参考以下文章

获取当前路线名称?

如何从 RouteData 获取路线名称?

按名称获取路线详细信息

Ember:模型更改时重新渲染路线的模板

Ember对测试路线钩子和动作感到困惑

javascript Ember的路线生命周期