我试图在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”不是注入器图的一部分......有人知道为什么会这样吗?提前感谢您的帮助(这让我疯了!) .
1 回答
是的,如果您需要通过
DI
使用该服务,那么parameters()
上的parameters()
关键字 . 这是设计 . 但是如果您需要使用Static
方法,那么您不需要通过DI
实例化该类 . 您可以使用它如下所示,当你在组件上需要它时: