【问题标题】:Angular 2 injecting a global dependencyAngular 2 注入全局依赖
【发布时间】:2016-02-09 17:58:25
【问题描述】:

我想做的是在每个组件中都有一个可用的服务,但我宁愿不必将它导入到所有组件中。 (显然,如果必须,我会的。)

我认为,也许是错误的,我可以做一些类似于在我的应用程序中引导 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:

Uncaught ReferenceError: WidgetService is not defined

在服务中使用@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. 您能否将服务全局注入所有组件,而无需手动将其导入每个组件。 (即:如果我愿意,可以在任何地方使用它。)
  2. 如果可以的话,谁能解释我做错了什么并告诉我如何正确地做。
  3. 感谢您的宝贵时间和回答!

【问题讨论】:

    标签: javascript dependency-injection typescript angular


    【解决方案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 中不知道服务的类型。

    【讨论】:

    • 那么,如果我在引导时使用“提供”添加它们,我可以做我想做的事吗?我还需要用@Injectable 装饰我的全球服务吗?
    • 其实@Injectable()在你的服务有构造函数参数需要DI解析的时候是必须的。 Angular 文档建议始终添加 @Injectable(),因为当您稍后向构造函数添加参数时,它更不容易出错。
    • 有哪些代码行的信息?第一版还是第二版?
    • 第二个,和你的很像
    • 我想我解决了这个问题,因为我的应用程序的其余部分不再工作了。但是,我将标记为正确,因为它解决了我的主要问题。谢谢!
    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2015-11-08
    • 1970-01-01
    • 2016-10-23
    • 2012-09-23
    相关资源
    最近更新 更多