【问题标题】:Why is my provider/service not found?为什么找不到我的提供者/服务?
【发布时间】:2017-03-25 09:14:39
【问题描述】:

据我所知,我已经按照 docs 创建了一个 CoreModule 以在 Angular 2.0.0 中提供我的服务。我还尝试了以下建议:

Provide core singleton services module in Angular 2

Angular2 RC5 ngModule: No Provider For NameService

无济于事。获得“连接”服务需要什么?我使用以下代码得到的错误是:

没有 AuthService 的提供者!

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';

//Modules/Components
import { AppComponent } from './app.component';
import { SignInModule } from './sign-in/signin.module';
import { CoreModule } from './services/core.module';

@NgModule({
    imports: [BrowserModule, AppRoutingModule, FormsModule,
        CoreModule, SignInModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
})
export class AppModule { }

services/core.module.ts

import { NgModule } from '@angular/core';

// Services
import { SignalRService } from './signalr.service';
import { AuthService } from './auth.service';
import { UserSettingsService } from './user-settings.service';

@NgModule({
    providers: [SignalRService, AuthService, UserSettingsService]
})
export class CoreModule {
}

services/auth.service.ts

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { SignalRService } from './signalr.service';
import { ISignInProvider } from '../sign-in/signin.interface';

@Injectable()
export class AuthService {
    constructor(private signalR: SignalRService, private router: Router) {
    }
..
}

登录/signin.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { GoogleSignInComponent } from './google-signin.component';

@NgModule({
    imports: [CommonModule, FormsModule],
    declarations: [GoogleSignInComponent],
    exports: [GoogleSignInComponent],
})
export class SignInModule { }

sign-in/google-signin.component.ts(我认为这是错误指向的地方)

import { Component, AfterViewInit } from '@angular/core';
import { AuthService } from '../services/auth.service';
import { ISignInProvider } from './signin.interface';

@Component({
    moduleId: module.id,
    selector: 'google-signin',
    templateUrl: 'google-signin.component.html',
})
export class GoogleSignInComponent implements AfterViewInit, ISignInProvider     {
    constructor(private authService: AuthService) {
    }
}

登录组件 在功能模块 (SignInModule) 中,但它是在应用模块中导入的。我尝试在CoreModule 中使用forRoot,但似乎没有效果。我无法让 SystemJS 别名按照另一个问题中的建议工作,但我不确定为什么这会解决任何问题。

不使用CoreModule 并将提供程序直接放在AppModule 上也不起作用。我没有将它们直接放在组件上,因为我认为这是不好的做法。据我所知,登录组件/模块不是延迟加载的,它不是路由器的一部分(它在应用程序组件模板中)。

我的错误在哪里,或者,我应该做些什么不同的事情?

【问题讨论】:

  • 向组件添加提供者并不是坏事。这取决于您实际尝试完成的工作。如果您想限制服务的范围,您必须使用延迟加载的模块或将其添加到组件中。我在您的代码中没有看到错误。我希望它能够工作。
  • @GünterZöchbauer 我并不是要限制范围,这些服务在整个应用程序中都会用到,所以我希望这种方法能够正常工作。如果让它工作的唯一方法是走组件路线,我会的。

标签: angular systemjs


【解决方案1】:

您必须在signin.module.ts 中为SignalRServiceAuthServiceUserSettingsService 添加提供程序。

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { GoogleSignInComponent } from './google-signin.component';

@NgModule({
    imports: [CommonModule, FormsModule],
    declarations: [GoogleSignInComponent],
    providers: [SignalRService, AuthService, UserSettingsService],
    exports: [GoogleSignInComponent],
})
export class SignInModule { }

或者您必须创建一个共享模块,其中包含 SignalRServiceAuthServiceUserSettingsService 的提供者声明,并且您必须在所有其他模块中导入此共享模块。

//SharedModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { GoogleSignInComponent } from './google-signin.component';

@NgModule({
    imports: [CommonModule, FormsModule],
    providers: [SignalRService, AuthService, UserSettingsService]
})
export class SharedModule { }

//SignInModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

import { SharedModule } from 'path to SharedModule';
import { GoogleSignInComponent } from './google-signin.component';

@NgModule({
    imports: [CommonModule, FormsModule, SharedModule],
    declarations: [GoogleSignInComponent],
    exports: [GoogleSignInComponent],
})
export class SignInModule { }

【讨论】:

  • 恕我直言,这应该只对指令、组件和管道是必需的,但对服务不是必需的(虽然我自己在这方面还没有进行太多调查)。
  • 我相信文档明确表示不要重新导入 CoreModule...我是遗漏了什么还是文档过时了?
  • 提供者(除了延迟加载的模块)总是添加到根 DI 范围内,因此在一个地方导入一个模块就足够了。在它所依赖的每个模块中导入一个模块以使依赖关系明显(使指令可用,如前所述)可能是一个好习惯,但我认为这不是必需的。 AFAIR 在文档中的某处提到,如果在多个地方导入这样的模块,则提供者将被重复数据删除,并且只有一个提供者将在根范围内注册。
  • @GünterZöchbauer 除了重新导入之外,我注意到他的SharedModule 导出服务并将它们放入提供者数组中,这是正确的还是应该只是在提供者中?另外,为了再次确定,我链接的文档中的这个声明不再正确? “只有根 AppModule 应该导入 CoreModule。如果延迟加载的模块导入它,就会发生坏事。”或者也许我需要导入,因为我的其他模块没有延迟加载?
  • “坏事”是 2 个实例,因为延迟加载的模块有自己的根范围,延迟加载的组件和服务不会获取全局实例,而是从延迟加载的模块获取实例。我不认为提供者需要被导出。我认为这仅适用于指令、组件和管道。我对这个话题不太确定,因为我正在使用 Dart 并且没有 NgModules
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2016-11-18
  • 2014-12-01
  • 2020-06-23
相关资源
最近更新 更多