简体   繁体   English

可以在Ember的服务中进行路由转换吗?

[英]Possible to make a route transition inside of a service in Ember?

I'm using ember-cli 1.13.8 and I have a service that handles most of my logic. 我正在使用ember-cli 1.13.8,我有一个处理大部分逻辑的服务。 Right now I have a function that listens to whether certain things are true or false and then can make a route change based upon that. 现在我有一个函数可以监听某些事情是真还是假,然后可以根据它来改变路由。 I'd rather not have to call that function from inside every route since I want it to happen on every route. 我宁愿不必从每条路线内部调用该功能,因为我希望它发生在每条路线上。 Its goal is to determine whether the player won and every interaction in the game drives this. 它的目标是确定玩家是否赢了,游戏中的每次互动都是如此。

Inside of my game service: 我的游戏服务内部:

init() {
  ... 
  if(true) {
    console.log("you've won!");
    this.transitionTo("congratulations");
  }
},

Of course, this fails because this isn't a route like Ember expects. 当然,这失败了,因为this不是像Ember期望的那样。 I know I can call this method from inside of every route instead but I'm wondering if there is a better way to do this. 我知道我可以从每条路线内部调用这种方法,但我想知道是否有更好的方法来做到这一点。

Thanks 谢谢

Edit 编辑

So far I've tried importing in the App and then trying to extend the Router. 到目前为止,我已尝试在应用程序中导入,然后尝试扩展路由器。 This seems like a bad idea though. 这似乎是一个坏主意。

You can use the routing service (which is a private API): 您可以使用路由服务(这是一个私有API):

routing: Ember.inject.service('-routing'),

init() {
  ... 
  if(true) {
    console.log("you've won!");
    this.get("routing").transitionTo("congratulations");
  }
},

As of Ember 2.15, there is a public router service for exactly this use case. 从Ember 2.15开始,有一个公共router服务正是这个用例。 Just add router: Ember.inject.service(), to your Ember class and call this.get('router').transitionTo(...); 只需将router: Ember.inject.service(),添加到您的Ember类并调用this.get('router').transitionTo(...); , easy! , 简单!


Generally this is a bad idea, but in some cases it's easier than passing through route actions in 100 places (personal experience). 通常这是一个坏主意,但在某些情况下,它比在100个地方通过路线行动(个人经验)更容易。

The better way to do this from anywhere is to look the router up on the container: 从任何地方执行此操作的更好方法是在容器上查找路由器:

Ember.getOwner(this).lookup('router:main').transitionTo(...);

this has to be some container allocated Ember object, which includes components, services, and Ember Data models. this必须是一些容器分配的Ember对象,其中包括组件,服务和Ember Data模型。

Note also that if this will be called a lot, you will want to store the router as a property. 另请注意,如果这将被大量调用,您将希望将路由器存储为属性。 You can do this in the init hook: 你可以在init钩子里做到这一点:

init() {
  this._super(...arguments);
  this.set('router', Ember.getOwner(this).lookup('router:main'));
}
...
this.get('router').transitionTo(...);

Ember.getOwner(this) works in Ember 2.3+ , prior to that you can use this.get('container') instead. Ember.getOwner(this)Ember 2.3+中工作 ,在此之前你可以使用this.get('container')代替。

Ember 1.13: 恩伯1.13:

Create another service called routing: 创建另一个名为routing的服务:

import Ember from 'ember';

export default Ember.Service.extend({
    _router: null,

    init() {
        this._super();

        this.set('_router', this.get('container').lookup('router:main'));
    },

    transitionTo() {
        this.get('_router').transitionTo(...arguments);
    }
});

Then you can: 那么你也能:

routing: Ember.inject.service(),

goSomewhere() {
    this.get('routing').transitionTo('index');
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM