编辑:由于我发现了更多关于这个问题的信息,因此很多问题被删除了。
我在控制台中收到此错误:
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;
}
}
答案 0 :(得分:1)
答案 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