Angular 2注入全局依赖

时间:2016-02-09 17:58:26

标签: javascript dependency-injection typescript angular

我想要做的是拥有每个组件都可用的服务,但我不希望将其导入所有组件。 (显然,如果必须,我会。)

我想,也许是错误的,我可以做类似的事情,就像我在我的应用程序中引导HTTP_PROVIDERS一样,这使得HTTP可用(如果我没弄错的话,这是必需的)。

例如,在我的app.ts文件中:

import { bootstrap } from 'angular2/platform/browser';
import { Injectable } from 'angular2/core';
import { HTTP_PROVIDERS } from 'angular2/http';
import 'rxjs/add/operator/map';
import { WidgetService } from './widget.service';
import { BuilderComponent } from './modules/builder/builder.component';

bootstrap(BuilderComponent, [HTTP_PROVIDERS, WidgetService]);

我希望这会使WidgetService在所有子/孙等组件中可用。 (BuilderComponent是有几个孩子/孙子的父母。)

使用@Inject注入它时出现的错误和@Injectable未在服务本身中使用:

  

未捕获的ReferenceError:未定义WidgetService

在服务中使用@Injectable时出错,而不是使用@Inject注入它:

  

无法解析'MyComponent'的所有参数(NonGlobalService,?)。确保所有参数都使用Inject进行修饰或具有有效的类型注释,并且'MyComponent'使用Injectable进行修饰。

我不确定为什么MyComponent需要使用Injectable进行修饰,但是当我使用@Injectable进行装饰时,我会得到同样的错误。

widget.service.ts

import { Injectable, NgZone } from 'angular2/core';

@Injectable()
class WidgetService {
    constructor(private _zone: NgZone) {
    }
    // other methods here...
}

export { WidgetService };

我是如何尝试注射的:

class MyComponent {
    constructor(private _nonGlobalService: NonGlobalService,
                private _widget: WidgetService) {
    }
}

总结:

  1. 您可以将服务全局注入所有组件,而无需手动将其导入每个组件。 (IE:如果我需要,可以随处使用。)
  2. 如果可以,有人可以解释我做错了什么,并告诉我如何正确地做到这一点。
  3. 感谢您的时间和答案!

1 个答案:

答案 0 :(得分:1)

有不同的方式。

您可以创建一个包装器服务,只注入这个服务。

@Injectable()
export class FooService {
  doFoo() {...};
}

@Injectable()
export class BarService {
  doBar() {...}
}

@Injectable()
export class GlobalService {
  constructor(public foo:FooService, public bar:BarService) {
  }
}

此处GlobalService需要导入

export class MyComponent {
  constructor(global:GlobalService) {
    global.foo.doFoo();
    global.bar.doBar();
  }
}

这样您就不需要为组件导入任何内容

bootstrap(AppComponent, [
    provide('foo', { useClass: FooService }), 
    provide('bar', { useClass: BarService })]);

export class MyComponent {
  constructor(@Inject('foo') foo, @Inject('bar') bar) {
    foo.doFoo();
    bar.doBar();
  }
}

但我不认为这第二种方法是可行的。您将无法获得任何IDE支持,因为MyComponent中的服务类型未知。