2017-08-14 44 views
2

我想在ionic3/angular4中使用依賴注入在另一個服務(而不是組件)中簡單使用服務。我想我已經明白如何做到這一點在理論上,但在實踐中,我一直struglying好幾天......ionic3/angular 4:在另一個服務不工作的服務注入

這裏是我的配置:

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文件(因爲我已經throught一些線程表明編譯選項可能會對注入的行爲有一定的影響)

{ 
    "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,其他:SettingsStorageProvider & TMDbApiProvider

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

這是我SettingsStorageProvider類,我可以做使用存儲 & 記錄器服務沒有問題LEM:

@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類,我不能讓注射服務記錄儀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:constructor - > logger is 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的 「進口」, 「entryComponents」 & 「提供者」: NgModule 並使用「占卜」 Chrome擴展一對myApp的噴射器圖形的視圖: Injector Graph

奇怪的是,「TMDbAPIProvider」聲明爲在根「NgModule」提供者不是注射器圖的一部分... 做一個人知道爲什麼這可能是? 非常感謝您的幫助(這使我變得瘋狂!)。

enter image description here

+0

我的猜測是,你打電話的地方''的新TMDbApiProvider(someValueOfAnyType),而不是使用DI。 –

+0

謝謝你猜@ jBNizet。 但我在 'MoviesHomePage' 組件使用DI爲TMDbApiProvider: '出口類MoviesHomePage { 構造(公共navCtrl:NavController,私人記錄:記錄儀, \t \t \t \t公共tmdbApi:TMDbApiProvider){.... ' – Eng

+0

好吧,似乎將「get」函數聲明爲靜態函數是我無法在另一個提供程序中注入此服務的原因:static get parameters(){[Http]]; '但是我不明白爲什麼...... – Eng

回答

0

是的,你必須如果需要通過DI。那是design.But如果你需要使用Static方法,那你就不要使用該服務中刪除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(); 
    } 
    } 
相關問題