如何在没有类型注入的应用程序启动时初始化Ember服务?

时间:2016-07-13 01:51:23

标签: ember.js

也许这有点深奥,但我需要一些帮助。

我的用例是时钟自动收报机。我想要一个init()启动计时器的服务。 (例如AJAX轮询服务)。我希望这可以从app启动开始,但我不希望将它注入到每个对象类型中。

我尝试了什么:

  1. 编写服务并在应用程序控制器中使用Ember.inject.service()
  2. 使用app.register(…, MyService.create(), {instantiate: false})初始化程序而不调用app.inject(…)
  3. 请勿在{{1​​}}而不是init()将计时器启动到应用程序路由/控制器及其Ember.inject.service()调用init()
  4. 以下是我遇到的一些绊脚石:

    1. 服务是延迟加载的,因此计时器永远不会启动,因为应用程序控制器从未执行this.get('myService').startTimer()。我可以在控制器的this.get('myService')中做到这一点但感觉就像代码味道
    2. 似乎ember解析器将看到init()文件并自动注册它。执行services/my-service.js似乎注册了两个实例,两者混淆了。
    3. 就像在应用程序控制器app.register()中获取延迟服务一样,此解决方案也感觉像代码味道。但是我尝试过的所有解决方案都是有效的,并且是三者中最不臭的。
    4. 还有其他选择吗?

1 个答案:

答案 0 :(得分:9)

TL; DR使用实例初始值设定项

实例初始化程序将具有所需的查找功能,以获取系统自动注册的服务并对其执行操作。

但是,为路由或控制器init()保存此初始化可能更合适,因为此处任何类似ajax的东西仍然属于Embers Loading状态和运行循环。虽然在实例中执行初始化程序会降低启动性能,但没有实际的好处。

如果您仍然觉得初始化程序是这里的方法,那么Ember 1.13和2.0兼容的人为例子:

// app/instance-initializers/start-my-service.js
export function initialize(app) {
  const { container = app } = app;
  const myService = container.lookup('service:my-service');
  myService.startPolling();
}

export default {
  initialize
};

example ember-twiddle