如何在角度2中使用Factory Provider

时间:2016-10-01 06:58:47

标签: angular typescript dependency-injection

我需要在Dim prev_date As String prev_date = Month(Date - 1) & "/" & Day(Date - 1) & "/" & Year(Date - 1) Thisworkbook.Sheets("Sheet1").Activate 'change this line with your sheet where pivot table is present. Change Sheet name. ActiveSheet.PivotTables("PivotTable1").RefreshTable ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").CurrentPage = prev_date 应用程序中将服务注入另一个服务。在阅读了我推断的文档之后,最好的方法是使用Factory Provider。然而,出现了两个问题:

1)文档建议创建一个带有两个“代码段”的angular 2类:

HeroServiceProvider

我的问题是课程应该如何?应该在哪里添加上述代码段?

2)如何/可以使用这家工厂?我明白了,它应该导入为:

let heroServiceFactory = (logger: Logger, userService: UserService) => {
  return new HeroService(logger, userService.user.isAuthorized);
};

export let heroServiceProvider =
  { provide: HeroService,
    useFactory: heroServiceFactory,
    deps: [Logger, UserService]
  };

然后如何检索和访问所需的参数化服务?

5 个答案:

答案 0 :(得分:16)

我在app_initalizer上注入相同的问题,经过长时间的搜索,我找到了下面的解决方案。可能这对您的方案有帮助。

@NgModule({
  imports: [ BrowserModule],
  ...
  providers: [
    {
      provide: HeroService,
      useFactory: heroServiceFactory,
      deps: [Logger, UserService],
      multi: true
    }
    ]
})
export class AppModule {}


export function heroServiceFactory = (logger: Logger, userService: UserService) => {
    return new HeroService(logger, userService.user.isAuthorized);
};

答案 1 :(得分:2)

我没有足够的观点来评论@mgmg的答案,但这里有一些有用的信息......

我在自己的应用程序中使用了docs(以及此问题的主题)中提供的提供程序工厂模式,但在编译时遇到错误

  

ERROR in Error遇到静态解析符号值。   不支持函数调用。考虑更换功能或   lambda引用导出函数...

基本上,当在根模块中使用工厂依赖项时,必须为其提供所有依赖项。

这意味着@mgmg的答案中给出的代码块应严格具有依赖服务

import { heroServiceProvider } from './hero.service.provider';
import { UserService } from './user.service';
import { Logger }      from './logger.service';

...

@NgModule({

  ...

  providers: [
    Logger,
    UserService,
    heroServiceProvider
    // Wrapper for:
    //{ provide: HeroService,
    //  useFactory: (logger: Logger, userService: UserService) => {
    //    return new HeroService(logger, userService.user.isAuthorized)
    //  },
    //  deps: [Logger, UserService]
    //};

  ],
  bootstrap: [ AppComponent ]
})

注意,在角度文档here中, heroes.component 中提供的 heroServiceProvider 不在 app.module 中,并且那里不需要对Logger和UserService的引用。我认为这两个依赖关系是从注入器树的较高位置获取的。

答案 2 :(得分:1)

1)问题的第一部分很简单:您只需将您提供的代码段保存在单独的文件中,然后将其导入组件中,如问题所示:

import { heroServiceProvider } from './hero.service.provider';

2)至于实际使用情况,您并不需要更改组件中与服务相关的代码。如果注入原始服务,请继续使用它。您甚至不需要修改组件构造函数。服务提供商的想法是,您可以通过为每个组件提供自定义服务提供程序来基于每个组件自定义服务,并且您可以在工厂函数中执行特定于组件的初始化。只是不要忘记在您的组件的装饰器中列出您的服务提供商,Angular正在自动处理其他事情"。

答案 3 :(得分:1)

问题1:
班级总体上应该如何?上面的代码段应该添加到哪里?

答案:
您可以创建一个文件,以包含用于英雄服务提供商及其工厂功能的代码。该文件可以命名为hero.service.provider.ts
并且,在另一个名为hero.service.ts的文件中编写用于英雄服务的代码。

查看有关how to use Angular Service Providers的本文,以查看更多示例。

hero.service.provider.ts文件:

import { HeroService } from './hero.service';
import { Logger } from './logger.service';
import { UserService } from './user.service';

let heroServiceFactory = (logger: Logger, userService: UserService) => {
  return new HeroService(logger, userService.user.isAuthorized);
};

export let heroServiceProvider =
  { provide: HeroService,
    useFactory: heroServiceFactory,
    deps: [Logger, UserService]
  };

问题2: 一个人应该/如何使用这家工厂?

答案:
按照您提供的示例代码,可以使用@Component装饰器中的provider字段和service can be injected通过类构造函数或使用Angular注入器对象为服务配置工厂。

但是,当工厂提供者以这种方式配置时,摇树不起作用。如果您需要摇树才能工作,请查看此Angular tree shakable service example

import { heroServiceProvider } from './hero.service.provider';
import { HeroService } from './hero.service';

@Component({
  selector: 'my-selector',
  template: ``,
  providers: [heroServiceProvider]
})
export class HeroComponent {
  constructor(private heroService: HeroService) { } 
}

答案 4 :(得分:0)

今天我遇到了同样的问题并找到了一些解决方案。

1)我在angular.io中找到了确切的代码,请参阅以下内容: https://github.com/angular/angular.io/blob/master/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.provider.ts(链接已于2017年3月15日更新) 从这段代码中,heroServiceProvider不需要是一个类。

2)在app.module.ts中,@ NgModule中有providers属性。你可以在下面添加heroServiceProvider:

import { heroServiceProvider } from './hero.service.provider';

...

@NgModule({

  ...

  providers: [
    heroServiceProvider
  ],
  bootstrap: [ AppComponent ]
})

通过在@NgModule中提供服务,您可以在应用程序范围内使用该服务。