首页 文章

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

提问于
浏览
2

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

这是我的配置:

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

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

{
  "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
  }
}

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

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

这是我的 SettingsStorageProvider 课程,我可以毫无问题地使用存储和 Logger 服务:

@Injectable()
export class SettingsStorageProvider {

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

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

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

这是我的 TMDbApiProvider 类,我无法使用注入的服务Logger或SettingsStorageProvider甚至认为它们似乎在 app.module.ts 中正确注册:

@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;
        });
    }
}

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

tmdb-api.ts:30 TMDbApiProvider:构造函数 - > logger为NULL! tmdb-api.ts:34 TMDbApiProvider:构造函数 - > http为NULL !!!

并出现以下错误:

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

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

@Injectable()
export class TMDbApiProvider {

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

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

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

并且错误也发生了变化:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'loadSettings' of undefined
TypeError: Cannot read property 'loadSettings' of undefined

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

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

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

根"NgModule"与myApp的"declarations","imports","entryComponents"和"providers":NgModule以及使用"Augury"的Chrome扩展程序的myApp注入器图的视图:Injector Graph

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

enter image description here

1 回答

  • 0

    是的,如果您需要通过 DI 使用该服务,那么 parameters() 上的 parameters() 关键字 . 这是设计 . 但是如果您需要使用 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();
         }
      }
    

相关问题