错误:ShopService没有提供商!在其他服务中使用服务

时间:2016-10-05 04:24:33

标签: angular angular2-services

编辑:由于我发现了更多关于这个问题的信息,因此很多问题被删除了。

我在控制台中收到此错误:

  

app / find-page / find-page.component.html中的错误:1:3导致:否   ShopService的提供商!

我使用ShopService的地方位于另一个名为ResultService的服务中。如何在ResultService中声明ShopService的提供程序?因为当我将ShopService添加到应用程序中唯一模块的提供者(appModule)时,它没有提供ShopService的提供者。

这是因为在appModule中没有声明ResultService,导致appModule中的提供程序不能用于ResultService吗?我会在AppModule中将其声明在哪里?因为我把它添加到appModule的声明中我得到了:

  

find:21错误:(SystemJS)声明的意外值'ResultService'   模块'AppModule'(...)

代码:

ResultService:

import { Injectable } from '@angular/core';
import { Result } from '../result';
import { RESULTS } from '../mock-results';
import { ShopService } from './shop.service';

@Injectable()
export class ResultService {

constructor(private shopService: ShopService) {}

  getResults(): Result[] {
    RESULTS.forEach(result => {
      result.nearbyShops = this.shopService.getShops();
    });
    return RESULTS;
  }
}

ShopService:

import { Shop } from '../result';
import { SHOPS } from '../mock-shops';
import { Injectable } from '@angular/core';

@Injectable()
export class ShopService {
  getShops(): Shop[] {
    return SHOPS;
  }
}

2 个答案:

答案 0 :(得分:1)

我和你有类似的错误

  

错误:无法解析服务的所有参数:(?,?,?)

我找到了一个在NgModule上提供我的服务的解决方案 看看我的回答here

我希望能帮助你。

答案 1 :(得分:0)

我有类似的问题 -
我的" MenuService"取决于" SecurityService"。
我在AppModule中提供了这两种服务,但是一旦我的MenuService被创建,我就得到了错误"没有SecurityService"的提供者。

我确信SecurityService存在,因为我可以在控制台上将其注销。

注意* - 这两个服务定义都是从外部npm包导入的,因为我想在其他项目中使用它们。所以这可能会对根本原因产生影响。

对我来说唯一的解决方案是创建一个MenuServiceFactory来提供MenuService并将SecurityService传递给构造函数。

示例测试用例 -

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { HeaderComponent } from './header.component';
import { provideRoutes } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { SecurityModule, SecurityService } from '@savantly/ngx-security';
import { MenuModule, MenuService } from '@savantly/ngx-menu';


const menuServiceFactory = (_securityService: SecurityService) => {
  return new MenuService(_securityService);
};

describe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ HeaderComponent ],
      imports: [RouterTestingModule, SecurityModule.forRoot(), MenuModule],
      providers: [
        {
          provide: MenuService,
          useFactory: menuServiceFactory,
          deps: [SecurityService]
        },
        provideRoutes([])
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(HeaderComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});  

如果您希望消费者更轻松地将此工厂移至原始模块中,

import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MenuComponent } from './menu.component';
import { MenuService } from './menu.service';
import { MdMenuModule, MdToolbarModule, MdButtonModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';
import { SecurityModule, SecurityService } from '@savantly/ngx-security';

@NgModule({
  imports: [
    CommonModule,
    MdMenuModule, MdToolbarModule, MdButtonModule, FlexLayoutModule, SecurityModule
  ],
  exports: [
    CommonModule,
    MdMenuModule, MdToolbarModule, MdButtonModule, FlexLayoutModule,
    SecurityModule,
    MenuComponent],
  declarations: [MenuComponent],
  providers: []
})
export class MenuModule {

  static forRoot({securityService = SecurityService}: {securityService?: SecurityService} = {}): ModuleWithProviders {
     return {
        ngModule: MenuModule,
        providers: [{
            provide: MenuService,
            useFactory: menuServiceFactory,
            deps: [securityService]
          }]
      };
  }

  constructor (@Optional() @SkipSelf() parentModule: MenuModule) {
    if (parentModule) {
      throw new Error(
        'MenuModule is already loaded. Import it in the AppModule only');
    }
  }
 }

export function menuServiceFactory(_securityService: SecurityService): MenuService {
  return new MenuService(_securityService);
}

参考文献 -
https://angular.io/guide/dependency-injection#factory-providers
https://github.com/savantly-net/sprout-platform