Emberjs中的实例初始化程序

Instance Initializers in Emberjs

本文关键字:初始化 程序 实例 Emberjs      更新时间:2023-09-26

我们正在经历将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();
  });
}

现在建议我将其拆分为一个"普通"初始化器来注册basket对象,以及一个实例初始化器来获取存储并调用我们的API服务器。然而,如果这样做,我将无法访问实例初始值设定项中的注册表来注册我的promise返回的对象,然后将其注入到我的控制器中。我想我想这一切都错了,但我还没能理解它。有什么建议我应该如何更新它吗?

我认为在这里发布@tomdale解释是合理的,以帮助其他人理解初始化项。

@tomdale:"不可能在实例初始化器中推迟应用程序的准备状态,因为根据定义,实例初始化器只有在应用程序完成引导后才能运行。

关于应用程序启动语义的边栏:"应用程序就绪"(如中的deferReadiness(advanceReadiness())指的是应用程序的所有代码是否已加载。一旦加载了所有代码,就会创建一个新的实例,这就是您的应用程序。

重申一下,在浏览器中运行的Ember应用程序的生命周期是:

  1. Ember负载
  2. 您创建一个Ember.Application实例全局(例如。应用程序)
  3. 到目前为止,还没有加载任何类
  4. 在评估JavaScript文件时,您可以在应用程序(例如App.MyController = Ember.Controller.extend(…);

  5. Ember等待DOM就绪,以确保您的所有JavaScript已加载通过CCD_ 4标签包含的。

  6. 初始化程序正在运行
  7. 如果您需要延迟加载代码或等待其他设置,可以调用deferReadiness()
  8. 加载完所有内容后,可以调用advanceReadiness()
  9. 在这一点上,我们说Application是准备好的换句话说,我们已经告诉Ember所有的课程组成应用程序的组件、路由、控制器等加载
  10. 将创建应用程序的新实例,并且实例初始化程序正在运行
  11. 路由开始,UI呈现到屏幕

如果您想延迟显示UI,因为需要进行一些运行时设置(例如,您想在应用程序开始运行之前打开WebSocket),则正确的解决方案是使用ApplicationRoute中的beforeModel/model/afterModel挂钩。所有这些钩子都允许您返回一个promise,该promise将防止在解决子路由之前对其进行评估。

在初始化器中使用deferReadiness()是许多人开始依赖的一种不幸的破解。我称之为破解,因为与路由器中的模型承诺链不同,它会破坏错误和加载子状态等问题。通过阻止初始化程序中的呈现,IMO为用户创造了更糟糕的体验,因为如果promise很慢或被拒绝,他们将看不到加载或错误子状态,而且我看到的大多数代码根本没有任何错误处理代码。这导致应用程序只需一个空白的白色屏幕就可以崩溃,并且不会向用户指示发生了什么不好的事情。"