Emberjs中的实例初始化器

时间:2015-06-24 13:11:50

标签: javascript ember.js dependency-injection

我们正在逐渐将我们的ember-cli应用程序更新到最新版本。我们落后了很多。我正处于引入实例初始化程序的阶段,我感觉这将打破我目前实现某个初始化程序的方式。

export function initialize(container, application) {
  var store = container.lookup('store:main');

  // We need a basket to be present when
  // the application loads. Wait for this
  // to happen before continuing.
  application.deferReadiness();

  store.findOrCreateRecord('order', basketToken).then(function(basket) {
    container.register('basket:main', basket, { instantiate: false });
    application.inject('controller:basket', 'model', 'basket:main');

    // Let the application know we have
    // a basket and can continue.
    application.advanceReadiness();
  });
}

现在推荐的是我将其拆分为“普通”初始化程序以注册篮子对象和实例初始化程序以获取存储并调用我们的API服务器。但是这样做我无法访问实例初始化程序中的注册表来注册我的promise中返回的对象,然后我将注入到我的控制器中。我想我认为这一切都错了,但我无法绕过它。有什么建议我应该通过更新吗?

1 个答案:

答案 0 :(得分:3)

我认为在此发布@tomdale explanation作为帮助其他人了解初始化程序的答案是合理的。

@tomdale :"无法在实例初始化程序中推迟应用程序准备就绪,因为根据定义,实例初始化程序仅在应用程序完成启动后运行。

关于应用程序启动语义的侧栏:"应用程序准备就绪" (如,deferReadiness()和advanceReadiness())指的是是否已加载应用程序的所有代码。加载完所有代码后,将创建一个新实例,即您的应用程序。

要重申,浏览器中运行的Ember应用程序的生命周期为:

  1. Ember loading。
  2. 您创建一个Ember.Application实例全局(例如 APP)。
  3. 此时,尚未加载任何类。
  4. 在评估您的JavaScript文件时,您可以在上面注册类 申请(例如App.MyController = Ember.Controller.extend(…);

  5. Ember等待DOM准备好确保您的所有JavaScript 通过<script>标记添加的内容已加载。

  6. 运行初始化程序。
  7. 如果您需要延迟加载代码或等待其他设置,可以致电deferReadiness()
  8. 加载完所有内容后,您可以致电advanceReadiness()
  9. 此时,我们说Application是 准备;换句话说,我们告诉Ember所有的课程 (构成应用程序的组件,路径,控制器等) 加载。
  10. 创建了一个新的应用程序实例和实例 初始化程序运行。
  11. 路由开始,UI呈现给 屏幕。
  12. 如果您想延迟显示UI,因为您需要进行一些运行时设置(例如,您希望在应用程序开始运行之前打开WebSocket),正确的解决方案是使用beforeModel/model/afterModel中的ApplicationRoute个钩子。所有这些钩子都允许您返回一个承诺,该承诺将阻止子路由在被解析之前被评估。

    在初始化程序中使用deferReadiness()是许多人都依赖的不幸黑客。我称之为黑客,因为与路由器中的模型承诺链不同,它会破坏错误和加载子状态等内容。通过阻止初始化程序中的呈现,IMO会为用户创建更糟糕的体验,因为如果承诺缓慢或拒绝,他们将看不到加载或错误子状态,并且我所看到的大多数代码都没有任何错误处理代码。这导致应用程序只能通过空白屏幕打破,并且没有向用户显示发生了不良事件。&#34;