TL; DR 25.10.16:更新
我重新命名标题以提供更多说明,因为我仍然关注正确的解决方案.
给定一个模块
@NgModule({
imports: [
ExternalModule.forRoot(config),
],
providers: [EXTERNAL_PROVIDERS(config)],
})
export class MyModule{}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:有没有可能我可以像这样通过我传递的配置注入依赖?
ExternalModule.forRoot(@Inject(MyConfig) config : MyConfig)providers: [EXTERNAL_PROVIDERS(@Inject(MyConfig) config)] (我不想{provide: xxx, deps :[xxx], useFactory : xxx}为每个给定的外部提供商创建.
我试图初始化Application Wide Service Locator与访问所描述的根注射器在这里,但角度2.1.0 ngDoBootstrap不能按预期工作.
旧帖子:
我想知道在Angular2中配置外部第三方库提供程序的正确模式是什么.
我们举一个例子(Typescript中的代码示例):
有一个库公开其提供者,并通过config对象文字提供一些配置选项:
export function THIRD_PARTY_PROVIDERS(config = {}): Provider[] {
return [
{
provide: ExtConfigurableService,
deps: [Http],
useFactory: (http: Http) => {
return new ExtConfigurableService(http, config);
}
},
ExtOtherService
];
}
Run Code Online (Sandbox Code Playgroud)
然后在客户端,这些提供商可以包含在 …
我正在通过APP_INITIALIZER以下方式从服务器预加载应用程序配置AppModule:
providers: [
ConfigService,
{
provide: APP_INITIALIZER,
useFactory: configServiceFactory,
deps: [ConfigService],
multi: true
}
],
Run Code Online (Sandbox Code Playgroud)
然后,ApiService从手动注入ConfigService:
@Injectable()
export class ConfigService {
private api: ApiService;
public constructor(
private injector: Injector
) {
// Avoid cyclid dependencies, inject manually:
this.api = injector.get(ApiService);
}
Run Code Online (Sandbox Code Playgroud)
最后router在注入时是不确定的ApiService
import { Http, Headers, RequestOptionsArgs, Response } from '@angular/http';
import { Router } from '@angular/router';
@Injectable()
export class ApiService {
constructor(
private router: Router,
private http: Http …Run Code Online (Sandbox Code Playgroud) 有没有办法通过服务名称获得角度为2的可注射服务的实例?
例如,在Angular 1中你可以写:
var service = $injector.get('ServiceName');
Run Code Online (Sandbox Code Playgroud)
并且service变量将获得服务的实例.
我真的很感谢你的帮助!
假设我有以下LazyModule是懒惰加载并在其中LazyComponent声明的内容:
@NgModule({
declarations: [LazyComponent],
providers: [LazyModuleService],
})
export class LazyModule { ...
@Component({
selector: 'my-lazy',
providers: [LazyComponentService]
})
export class LazyComponent { ...
Run Code Online (Sandbox Code Playgroud)
我的理解是,当加载LazyModuleangular时会为这个模块创建一个子注入器rootInjector,如下所示:
var lazyModuleInjector = rootInjector.resolveAndCreateChild([LazyModuleService]);
Run Code Online (Sandbox Code Playgroud)
然后创建一个这样的子注入器LazyComponent:
var lazyModuleInjector = lazyModuleInjector.resolveAndCreateChild([LazyComponentService]);
Run Code Online (Sandbox Code Playgroud)
所以最终注入器树是这样的:
这是对的吗?
我正在尝试在Angular 2中创建一个通用数据服务,我遇到了一个奇怪的错误.本质上,我正在创建一个HTTP服务,其方法包含api url的一部分,以便我可以将它用于多种情况.例如,我想传递'projects /'并加入'api /'来获取'api/projects /'然后我可以在http调用中使用它.
我目前的dataService.ts:
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/map'
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../app.constants';
@Injectable()
export class DataService {
private actionUrl: string;
private headers: Headers;
constructor(private _http: Http, private _configuration: Configuration, public action: string) {
this.actionUrl = _configuration.ApiUrl
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json');
}
public GetAll (action: string): Observable<any> {
return this._http.get(this.actionUrl + action).map((response: Response) => …Run Code Online (Sandbox Code Playgroud) 假设我有一个类Foo为其所有派生类提供依赖注入服务,如下所示:
export class Foo {
protected fb : FormBuilder;
protected router : Router;
protected otherService : OtherService;
protected anotherService : AnotherService;
constructor(injector : Injector) {
this.fb = injector.get(FormBuilder);
this.router = injector.get(Router);
this.otherService = injector.get(OtherService);
this.anotherService = injector.get(AnotherService);
}
Run Code Online (Sandbox Code Playgroud)
它具有从它派生的类:
export class Bar extends Foo {
constructor(injector : Injector){
super(injector);
}
}
Run Code Online (Sandbox Code Playgroud)
如何正确地对父类进行单元测试,而不会遇到:
Error: Can't resolve all parameters for Foo: (?)
目前我已经(尝试了很多很多不同的东西来让它工作,但失败了:()
export function main() {
describe('Class: Foo', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [ …Run Code Online (Sandbox Code Playgroud) 我在组件的 HTML 部分使用了一个自定义管道。它在模块中声明:
declarations: [ I18nPipe ],
Run Code Online (Sandbox Code Playgroud)
我希望能够从组件代码(而不是transform方法)调用它的方法。
我希望管道实例位于依赖注入上下文中的某个地方,以便我可以抓住它。但是我错了。如果我将它注入到组件的构造函数中(例如,像任何普通服务一样):
constructor(private i18nPipe: I18nPipe)
Run Code Online (Sandbox Code Playgroud)
然后我得到一个错误:没有提供者。所以我将它包含在providers同一模块的部分中:
providers: [ I18nPipe ]
Run Code Online (Sandbox Code Playgroud)
然后我将可以在组件代码中访问它,但是我的自定义管道会有两个实例。
创建者providers,在 DI 上下文中可用。在构造函数中注入时,我将获得此实例,因此我将在我的组件代码中使用此实例。
在 HTML 中使用的实例。它在哪里生活?我想在我的组件代码中访问这个实例,而不是“提供的”一个;我怎样才能获得它?
以下是angular.io的代码片段:
{ provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService] }
...
export function runnersUpFactory(take: number) {
return (winner: Hero, heroService: HeroService): string => {
/* ... */
};
};
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么deps在这里使用房产?使用的一般情况是deps什么?