【发布时间】:2017-12-07 16:03:27
【问题描述】:
我正在尝试在包含platformBrowserDynamic.bootstrapModule(AppModule) 的 main.ts 文件中使用服务authService;
该服务处理用户身份验证和令牌更新,我们希望它在应用程序启动之前获取用户令牌。这将避免引导应用程序、重定向到身份验证网页,然后再次引导应用程序。
下面是我们如何处理 JIT 编译器的问题,它确实有效。但是,如果您想利用 AOT(我们这样做),这将不起作用。
// main.ts
... imports ...
let windw: Window = window;
let authService = windw['authService'] = windw['authService'] || new AuthService();
authService.userLoadededEvent
.subscribe(user => {
if (location.pathname.match(/silentrenew/)) {
authService.completeSilentRenew();
} else if (user && !user.expired) {
platformBrowserDynamic().bootstrapModule(AppModule(authService));
} else {
if (location.hash.match(/id_token/)) {
authService.completeSignIn()
} else {
if (location.pathname.length > 1) {
let deeplink = location.href.replace(baseHref, '');
localStorage.setItem('deeplink', deeplink);
}
authService.signIn();
}
}
});
// AppModule
export const AppModule = (authService: AuthService = null) => {
@NgModule({
declarations: [
AppComponent
],
imports: [...],
providers: [
{
provide: AuthService,
useValue: authService
}
],
bootstrap: [AppComponent]
})
class AppModule { };
return AppModule;
}
如前所述,这种方法适用于 JIT 编译,但我希望应用程序进行 AOT 编译。当我使用上面的代码进行 AOT 编译时,我从 angular 得到以下错误。 Unhandled Promise rejection: No NgModule metadata found for 'AppModule'. ; Zone: <root> ; Task: Promise.then ; Value: Error: No NgModule metadata found for 'AppModule'.
有人知道我该如何解决这个问题吗? AuthService 需要是单例的,并且需要在引导的应用程序内部和外部进行访问。
我尝试过的事情。
我尝试将 AppModule 更新为不是一个函数,而只是一个类声明,其中包含一个使用窗口 obj 中的 AuthService 的提供程序。但是,角度似乎无法访问附加了 authService 的窗口 obj。这导致 AuthService 为undefined 例如
//AppModule
let windw: Window = window;
@NgModule({
declarations: [
AppComponent
],
imports: [...],
providers: [
{
provide: AuthService,
useValue: windw['authService'] // undefined
}
],
bootstrap: [AppComponent]
})
class AppModule { };
我还尝试将 AuthService 传递给 bootstrapModule() 方法。这不会导致任何引导错误,但随后我收到一个未提供AuthService 的注入器错误。我承认,我不完全确定 angular 对 bootstrapModule 的 CompilerOptions 输入上的 providers 属性做了什么。
app.component.html:18 ERROR Error:
StaticInjectorError[AuthService]:
NullInjectorError: No provider for AuthService!
// main.ts
... imports ...
let windw: Window = window;
let authService = windw['authService'] = windw['authService'] || new AuthService();
authService.userLoadededEvent
.subscribe(user => {
if (location.pathname.match(/silentrenew/)) {
authService.completeSilentRenew();
} else if (user && !user.expired) {
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [{provide: AuthService, useValue: authService}]
});
} else {
if (location.hash.match(/id_token/)) {
authService.completeSignIn()
} else {
if (location.pathname.length > 1) {
let deeplink = location.href.replace(baseHref, '');
localStorage.setItem('deeplink', deeplink);
}
authService.signIn();
}
}
});
// AppModule
export const AppModule = (authService: AuthService = null) => {
@NgModule({
declarations: [
AppComponent
],
imports: [...],
providers: [],
bootstrap: [AppComponent]
})
class AppModule { };
return AppModule;
}
再次感谢您的帮助。
【问题讨论】:
-
也许 forwardRef 是您想要的?基本上在定义之前添加对 authService 的引用,允许您提前使用它。 angular.io/api/core/forwardRef
标签: javascript angular dependency-injection