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

Suk*_*ima 6 ember.js

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

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

我尝试过的:

  1. 编写服务并Ember.inject.service()在应用程序控制器中使用.
  2. 使用初始化程序app.register(…, MyService.create(), {instantiate: false})而不调用app.inject(…).
  3. 不要启动计时器的init(),而不是Ember.inject.service()它到应用程序的路由/控制器和其init()通话this.get('myService').startTimer().

以下是我遇到的一些绊脚石:

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

还有其他选择吗?

Suk*_*ima 9

TL; DR使用实例初始化程序

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

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

如果你还是觉得初始化是去这里的路是一个人为的例子,既灰烬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
};
Run Code Online (Sandbox Code Playgroud)

一个例子是余烬.