Angular 6 注入器中提供的通用服务需要另一个应用程序注入变量
Angular 6 Universal service provided in Injector needs another app injected variable
我正在使用 Angular 通用。我创建了一个 PlatformService
来检测我当前正在使用哪个平台。
/* platform.service.js */
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
@Injectable({
providedIn: 'root'
})
export class PlatformService {
constructor(
@Inject(PLATFORM_ID) private platformId: Object
) {
this.platformId; // this is coming out undefined
}
isBrowser() {
return isPlatformBrowser(this.platformId);
}
isServer() {
return isPlatformServer(this.platformId);
}
}
我正在创建一个 BaseComponent
用于常规处理我的路由绑定组件。
/* base.component.ts */
import { Component, OnInit, Inject } from '@angular/core';
import { InjectorHolderService } from '@core/services/util/injector-holder.service';
import { PlatformService } from '@core/services/util/platform.service';
@Component({
selector: 'app-base',
template: '',
})
export class BaseComponent implements OnInit {
protected platformService: PlatformService;
constructor() {
this.platformService = InjectorHolderService.injector.get(PlatformService);
console.log(this.platformService);
}
}
由于这个组件会被很多组件继承,所以我不想通过super()
传递PlatformService
。所以我决定创建一个 Injector
.
/* app.module.ts */
import { InjectorHolderService } from '@core/services/util/injector-holder.service';
import { PlatformService } from '@core/services/util/platform.service';
@NgModule({ ... })
export class AppModule {
constructor() {
InjectorHolderService.injector = Injector.create({
providers: [
{
provide: PlatformService,
useClass: PlatformService,
deps: [], // I think i need to put something here, but not sure.
}
]
});
}
}
还有一个服务可以保存所有注入的模块以供将来使用。
/* injector-holder.service.ts */
import { Injectable, Injector } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class InjectorHolderService {
static injector: Injector;
}
但是 @Inject(PLATFORM_ID) private platformId: Object
发出 undefined
,因此我无法检测到平台。
我在这里错过了什么?或者如果有更好的方法可以实现上述功能。
如果你们需要查看任何其他文件,请告诉我。
我不确定以下方法是好是坏,目前,这是唯一对我有用的方法。很想听听任何新方法。
由于 PlatformService
需要 @Inject(PLATFORM_ID)
,它仅由 AppModule
提供,我创建的新 Injector
无法找到 @Inject(PLATFORM_ID)
的任何值因此未定义。
所以,现在我使用 PlatformService
的实例化对象,而不是在 Injector
中使用 class PlatformService
,因此能够访问 PlatformService
中的所有内容=19=].
修改我的 AppModule
如下:
/* app.module.ts */
import { InjectorHolderService } from '@core/services/util/injector-holder.service';
import { PlatformService } from '@core/services/util/platform.service';
@NgModule({ ... })
export class AppModule {
constructor(
private platformService: PlatformService,
) {
InjectorHolderService.injector = Injector.create({
providers: [
{
provide: PlatformService,
useValue: this.platformService, // notice the change of key, using value not class
deps: [],
}
]
});
}
}
将尝试添加一个最小的 repo 来重现这个问题并与大家分享,如果有人想探索更多。
我正在使用 Angular 通用。我创建了一个 PlatformService
来检测我当前正在使用哪个平台。
/* platform.service.js */
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
@Injectable({
providedIn: 'root'
})
export class PlatformService {
constructor(
@Inject(PLATFORM_ID) private platformId: Object
) {
this.platformId; // this is coming out undefined
}
isBrowser() {
return isPlatformBrowser(this.platformId);
}
isServer() {
return isPlatformServer(this.platformId);
}
}
我正在创建一个 BaseComponent
用于常规处理我的路由绑定组件。
/* base.component.ts */
import { Component, OnInit, Inject } from '@angular/core';
import { InjectorHolderService } from '@core/services/util/injector-holder.service';
import { PlatformService } from '@core/services/util/platform.service';
@Component({
selector: 'app-base',
template: '',
})
export class BaseComponent implements OnInit {
protected platformService: PlatformService;
constructor() {
this.platformService = InjectorHolderService.injector.get(PlatformService);
console.log(this.platformService);
}
}
由于这个组件会被很多组件继承,所以我不想通过super()
传递PlatformService
。所以我决定创建一个 Injector
.
/* app.module.ts */
import { InjectorHolderService } from '@core/services/util/injector-holder.service';
import { PlatformService } from '@core/services/util/platform.service';
@NgModule({ ... })
export class AppModule {
constructor() {
InjectorHolderService.injector = Injector.create({
providers: [
{
provide: PlatformService,
useClass: PlatformService,
deps: [], // I think i need to put something here, but not sure.
}
]
});
}
}
还有一个服务可以保存所有注入的模块以供将来使用。
/* injector-holder.service.ts */
import { Injectable, Injector } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class InjectorHolderService {
static injector: Injector;
}
但是 @Inject(PLATFORM_ID) private platformId: Object
发出 undefined
,因此我无法检测到平台。
我在这里错过了什么?或者如果有更好的方法可以实现上述功能。
如果你们需要查看任何其他文件,请告诉我。
我不确定以下方法是好是坏,目前,这是唯一对我有用的方法。很想听听任何新方法。
由于 PlatformService
需要 @Inject(PLATFORM_ID)
,它仅由 AppModule
提供,我创建的新 Injector
无法找到 @Inject(PLATFORM_ID)
的任何值因此未定义。
所以,现在我使用 PlatformService
的实例化对象,而不是在 Injector
中使用 class PlatformService
,因此能够访问 PlatformService
中的所有内容=19=].
修改我的 AppModule
如下:
/* app.module.ts */
import { InjectorHolderService } from '@core/services/util/injector-holder.service';
import { PlatformService } from '@core/services/util/platform.service';
@NgModule({ ... })
export class AppModule {
constructor(
private platformService: PlatformService,
) {
InjectorHolderService.injector = Injector.create({
providers: [
{
provide: PlatformService,
useValue: this.platformService, // notice the change of key, using value not class
deps: [],
}
]
});
}
}
将尝试添加一个最小的 repo 来重现这个问题并与大家分享,如果有人想探索更多。