ionic3 / angular 4:在另一个不工作的服务中注入服务

时间:2017-08-14 17:04:17

标签: angular typescript dependency-injection ionic3

我试图在ionic3 / angular4中使用依赖注入在另一个服务(而不是组件)中简单地使用服务。我以为自己已经理解了如何在理论上做到这一点,但实际上我已经好几天了......

这是我的配置:

export class Converter {
   static toFoo(bar: Bar) : Foo {}
   static toBar(foo: Foo) : Bar {}
}

这是我的 tsconfig.json 文件(因为我已经完成了一些线程,建议编译选项可能会对注入行为产生一些影响)

cli packages:
    @ionic/cli-plugin-ionic-angular : 1.4.1
    @ionic/cli-utils                : 1.7.0
    ionic (Ionic CLI)               : 3.7.0
local packages:
    @ionic/app-scripts : 2.1.3
    Ionic Framework    : ionic-angular 3.6.0

在我的 app.module.ts 中,我通过导入相关模块注册了一些服务: NgLoggerModule & IonicStorageModule ,其他人通过将它们添加到提供者数组: SettingsStorageProvider & TMDbApiProvider

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "es5"
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": false,
  "atom": {
    "rewriteTsconfig": false
  }
}

这是我的 SettingsStorageProvider 类,我可以使用 storage & logger 服务没有问题:

@NgModule({
....
imports: [
    IonicStorageModule.forRoot(),
    NgLoggerModule.forRoot(Level.LOG)
],
providers: [
    ....
    SettingsStorageProvider,
    TMDbApiProvider
]

这是我的 TMDbApiProvider 类,我无法使用注入的服务 Logger SettingsStorageProvider 甚至认为它们似乎在< strong> app.module.ts :

@Injectable()
export class SettingsStorageProvider {

    constructor(public storage: Storage, public logger: Logger) {
        this.logger.log('Hello SettingsStorageProvider');
    }

    public saveSettings(_settings: SettingsModel){
    .... }

    public loadSettings(): Promise<SettingsModel> {
    ....}
}

我在编译时没有错误,但在运行时,我得到了以下我在构造函数中放入的调试日志:

  

tmdb-api.ts:30 TMDbApiProvider:构造函数 - &gt; logger为NULL !!!

     

tmdb-api.ts:34 TMDbApiProvider:构造函数 - &gt; http为NULL !!!

并出现以下错误:

@Injectable()
export class TMDbApiProvider {

static get parameters() {
    return [[Http]];
}
    constructor(public settingsStorage: SettingsStorageProvider, public http: Http, 
    public logger: Logger) {
     if (settingsStorage == null)
         console.log('TMDbApiProvider:constructor-->settingsStorage is NULL !!!');
     if (logger  == null)
         console.log('TMDbApiProvider:constructor-->logger is NULL !!!');
     if (http == null)
         console.log('TMDbApiProvider:constructor-->http is NULL !!!');
}

    searchMovies(movieName) {
        this.settingsStorage.loadSettings().then((_settings) => {
        .....
            var url = Config.data.tmdb_searchService + encodeURI(movieName) + '&'+Config.data.tmdb_apiKey+'&'+Config.data.tmdb_language+_userSettings.getLanguage();
            var response = this.http.get(url).map(res => res.json());

            return response;
        });
    }
}

如果我在构造函数中反转注入服务的顺序:

ERROR Error: Uncaught (in promise): TypeError: _this.settingsStorage.loadSettings is not a function
TypeError: _this.settingsStorage.loadSettings is not a function
    at tmdb-api.ts:48
    at new t (polyfills.js:3)
    at TMDbApiProvider.webpackJsonp.171.TMDbApiProvider.searchMovies

我在构造函数中添加了不同的调试日志:

  

TMDbApiProvider:构造函数 - &gt; settingsStorage为NULL !!!   tmdb-api.ts:31 TMDbApiProvider:构造函数 - &gt; logger为NULL !!!

并且错误也发生了变化:

@Injectable()
export class TMDbApiProvider {

    constructor(public http: Http, public logger: Logger,
    public settingsStorage: SettingsStorageProvider) {

似乎只注入了第一个调用 TMDbApiProvider 构造函数的服务。

有人曾经遇到过这种奇怪的行为吗? 提前感谢您提供给我的任何帮助。

[15/08/2017] 以下是我的问题的补充信息:

根“NgModule”带有“声明”,“导入”,“entryComponents”和&amp; myApp的“提供者”: NgModule 并使用“Augury”Chrome扩展程序查看myApp的进样器图: Injector Graph

奇怪的是,在根“NgModule”中声明为提供者的“TMDbAPIProvider”不是注入器图的一部分...... 有人知道为什么会这样吗? 提前感谢您的帮助(这让我疯了!)。

enter image description here

1 个答案:

答案 0 :(得分:0)

是的,如果您需要通过static使用该服务,必须删除 parameters()方法上的DI关键字。这是设计使然。但是如果您需要使用Static方法,然后您不需要通过DI实例化该类。当您在组件上需要它时,可以像下面一样使用它:

import { TMDbApiProvider } from './TMDbApiProvider';

export class YourComponent {

    constructor() {
        // This is just an example of accessing the static members of a class.
        // Note: we didn't inject the service, nor manually instantiate it 
        let value = TMDbApiProvider.parameters();
     }
  }