Angular 通用状态转移初始化器

Angular Universal State Transfer Initializer

如何正确使用这个模块https://github.com/angular/universal/tree/master/modules/common/src/state-transfer-initializer

删除文档 DOMContentLoaded 并使用此模块后,状态传输在浏览器中停止工作。使用此模块的正确方法是什么?

P.S。已在@nguniversal/common@7.1.0 版本中修复,PR https://github.com/angular/universal/commit/0e38dd1

If DOMContentLoaded event already fired and after adding a listener for DOMContentLoaded event, then it will not execute.

We can check whether document is loaded or not by the following check.

if (doc.readyState === "complete" || doc.readyState === "interactive") {
    // document is ready
}

If DOMContentLoaded is not fired then we can listen to it.

function handler() {
    // After DOMContentLoaded
}
document.addEventListener('DOMContentLoaded', handler);

所以我们需要 resolve() 如果 DOMContentLoaded 已经解雇的承诺。我修改了Angular UniversalStateTransferInitializerModule模块代码,下面是代码。

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { DOCUMENT } from '@angular/common';

export function domContentLoadedFactory(doc: Document) {
  return () => new Promise ((resolve, _reject) => {
    const contentLoaded = () => {
      doc.removeEventListener('DOMContentLoaded', contentLoaded);
      resolve();
    };
    if (doc.readyState === "complete" || doc.readyState === "interactive") {
      // if DOMContentLoaded already fired
      // document is already ready to go
      resolve();
    }
    else{
      // if DOMContentLoaded is not fired then we are listening the event.
      doc.addEventListener('DOMContentLoaded', contentLoaded);
    }
  });
}


@NgModule({
  providers: [
    {provide: APP_INITIALIZER, multi: true, useFactory: domContentLoadedFactory, deps: [DOCUMENT]},
  ]
})
export class StateTransferInitializerModule {

}

为了参考添加了 stackblitz 代码。