单例动态提供程序 - Angular 7
Dynamic provider for singleton - Angular 7
我有一个 angular 应用程序,它可以显示视频或文章列表以及视频的详细信息或文章的详细信息。
我得到了 ContentListPage 和 ContentDetailsPage,它们对于视频或文章是一样的。
唯一的区别在于服务层,它基本上从 youtube 或 worpress 获取数据。
我只想根据当前内容类型动态提供一项通用服务。
我能够拥有动态提供者,但因为我使用的是工厂提供者,所以每次创建组件时都会创建一个新的服务实例。
我的主要尝试是基于factory provider
所以我定义了useFactory应该提供什么样的服务。
这运行良好,但是当我从 ContentListPage 导航到 ContentDetailsPage 时,会创建一个新的服务实例。
我知道这是因为我提供服务的方式
@Component({
. . .
providers: [contentServiceProvider]
})
但我找不到如何在没有后遗症的情况下提供另一个级别。
content.service.provider.ts
const contentServiceFactory = (http: HttpService, metaMediaService: MetaMediaService) => {
let contentService;
if (metaMediaService.currentMetaMedia.type === MetaMediaType.WORDPRESS) {
contentService = new MediasService(http, metaMediaService);
} else {
contentService = new YoutubeService(http, metaMediaService);
}
return contentService;
};
export let contentServiceProvider = {
provide: ContentService,
useFactory: contentServiceFactory,
deps: [HttpService, MetaMediaService]
};
@Component({
. . .
providers: [contentServiceProvider]
})
export class ContentListPage implements OnInit {
constructor(public mediasService: ContentService<IContent>) {
内容-details.page.ts
@Component({
. . .
providers: [contentServiceProvider]
})
export class ContentDetailsPage implements OnInit {
constructor(public contentService: ContentService<IContent>) { }
content.service.ts
@Injectable({
providedIn: 'root'
})
export abstract class ContentService<T extends IContent> {
abstract getContentById(id: number): Observable<T>;
abstract getContents(): Observable<T[]>;
abstract loadMore(): Observable<T[]>;
}
向朋友请教了一些建议,我们得出使用注射器的结论:
const contentServiceFactory = (metaMediaService: MetaMediaService, injector: Injector) => {
if (metaMediaService.currentMetaMedia.type === MetaMediaType.WORDPRESS) {
return injector.get(MediasService);
} else {
return injector.get(YoutubeService);
}
};
export let contentServiceProvider = {
provide: ContentService,
useFactory: contentServiceFactory,
deps: [MetaMediaService, Injector]
};
我有一个 angular 应用程序,它可以显示视频或文章列表以及视频的详细信息或文章的详细信息。
我得到了 ContentListPage 和 ContentDetailsPage,它们对于视频或文章是一样的。
唯一的区别在于服务层,它基本上从 youtube 或 worpress 获取数据。
我只想根据当前内容类型动态提供一项通用服务。 我能够拥有动态提供者,但因为我使用的是工厂提供者,所以每次创建组件时都会创建一个新的服务实例。
我的主要尝试是基于factory provider
所以我定义了useFactory应该提供什么样的服务。 这运行良好,但是当我从 ContentListPage 导航到 ContentDetailsPage 时,会创建一个新的服务实例。
我知道这是因为我提供服务的方式
@Component({
. . .
providers: [contentServiceProvider]
})
但我找不到如何在没有后遗症的情况下提供另一个级别。
content.service.provider.ts
const contentServiceFactory = (http: HttpService, metaMediaService: MetaMediaService) => {
let contentService;
if (metaMediaService.currentMetaMedia.type === MetaMediaType.WORDPRESS) {
contentService = new MediasService(http, metaMediaService);
} else {
contentService = new YoutubeService(http, metaMediaService);
}
return contentService;
};
export let contentServiceProvider = {
provide: ContentService,
useFactory: contentServiceFactory,
deps: [HttpService, MetaMediaService]
};
@Component({
. . .
providers: [contentServiceProvider]
})
export class ContentListPage implements OnInit {
constructor(public mediasService: ContentService<IContent>) {
内容-details.page.ts
@Component({
. . .
providers: [contentServiceProvider]
})
export class ContentDetailsPage implements OnInit {
constructor(public contentService: ContentService<IContent>) { }
content.service.ts
@Injectable({
providedIn: 'root'
})
export abstract class ContentService<T extends IContent> {
abstract getContentById(id: number): Observable<T>;
abstract getContents(): Observable<T[]>;
abstract loadMore(): Observable<T[]>;
}
向朋友请教了一些建议,我们得出使用注射器的结论:
const contentServiceFactory = (metaMediaService: MetaMediaService, injector: Injector) => {
if (metaMediaService.currentMetaMedia.type === MetaMediaType.WORDPRESS) {
return injector.get(MediasService);
} else {
return injector.get(YoutubeService);
}
};
export let contentServiceProvider = {
provide: ContentService,
useFactory: contentServiceFactory,
deps: [MetaMediaService, Injector]
};