【问题标题】:Dynamic provider for singleton - Angular 7单例的动态提供程序 - Angular 7
【发布时间】:2019-12-06 19:06:51
【问题描述】:

我有一个 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>) {

content-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[]>;
}

【问题讨论】:

    标签: angular typescript provider


    【解决方案1】:

    请教朋友一些建议,我们总结使用注射器:

    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]
    };
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-01
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多