我有HeroMockService这将返回模拟数据HeroService,并将回调终端服务从数据库中检索英雄.
假设Angular2已建立的环境,我打算注入HeroMockService到AppComponent如果当前构建环境"dev-mock".如果是当前构建环境"dev-rest",则HeroService应该注入AppComponent.
我想知道如何实现这一目标?
Pau*_*tha 24
IMO,更好的选择是使用angular-in-memory-web-api.它嘲笑使用的后端Http,因此它不是进行实际的XHR调用,而是抓取您提供给它的数据.要获得它,只需安装
npm install --save angular-in-memory-web-api
Run Code Online (Sandbox Code Playgroud)
要创建数据库,请createDb在您的实现中实现该方法InMemoryDbService
import { InMemoryDbService } from 'angular-in-memory-web-api'
export class MockData implements InMemoryDbService {
let cats = [
{ id: 1, name: 'Fluffy' },
{ id: 2, name: 'Snowball' },
{ id: 3, name: 'Heithcliff' },
];
let dogs = [
{ id: 1, name: 'Clifford' },
{ id: 2, name: 'Beethoven' },
{ id: 3, name: 'Scooby' },
];
return { cats, dogs, birds };
}
Run Code Online (Sandbox Code Playgroud)
然后配置它
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
@NgModule({
imports: [
HttpModule,
InMemoryWebApiModule.forRoot(MockData, {
passThruUnknownUrl: true
}),
]
})
Run Code Online (Sandbox Code Playgroud)
现在,当您使用Http并向其发出请求时/api/cats,将从数据库中获取所有猫.如果你去/api/cats/1它会得到第一只猫.您可以执行所有CRUD操作,GET,POST,PUT,DELETE.
需要注意的一点是,它需要一个基本路径.在示例中/api是基本路径.您还可以在配置中配置根(与基础不同)路径
InMemoryWebApiModule.forRoot(MockData, {
rootPath: 'root',
passThruUnknownUrl: true // forwards request not in the db
})
Run Code Online (Sandbox Code Playgroud)
现在你可以使用了/root/api/cats.
关于如何从开关切换到生产的问题,您可以使用工厂来创建提供者.如果您要使用模拟服务而不是内存中的web-api,情况也是如此
providers: [
Any,
Dependencies
{
// Just inject `HeroService` everywhere, and depending
// on the environment, the correct on will be chosen
provide: HeroService,
useFactory: (any: Any, dependencies: Dependencies) => {
if (environment.production) {
return new HeroService(any, dependencies);
} else {
return new MockHeroService(any, dependencies);
}
},
deps: [ Any, Dependencies ]
]
Run Code Online (Sandbox Code Playgroud)
至于in-memory-web-api,我需要回复你(我需要测试一个理论).我刚开始使用它,并没有达到我需要切换到生产的程度.现在我只有上面的配置.但我确信有一种方法可以让它工作而不必改变任何东西
好吧,对于im-memory-web-api我们可以做的而不是导入模块,就是提供XHRBackend模块提供的功能.这XHRBackend是Http用于进行XHR调用的服务.内存中的wep-api嘲笑这项服务.这就是所有模块所做的.所以我们可以使用工厂自己提供服务
@NgModule({
imports: [ HttpModule ],
providers: [
{
provide: XHRBackend,
useFactory: (injector: Injector, browser: BrowserXhr,
xsrf: XSRFStrategy, options: ResponseOptions): any => {
if (environment.production) {
return new XHRBackend(browser, options, xsrf);
} else {
return new InMemoryBackendService(injector, new MockData(), {
// This is the configuration options
});
}
},
deps: [ Injector, BrowserXhr, XSRFStrategy, ResponseOptions ]
}
]
})
export class AppHttpModule {
}
Run Code Online (Sandbox Code Playgroud)
请注意BrowserXhr,XSRFStrategy和ResponseOptions依赖.这就是原创XHRBackend的创作方式.现在,不要导入HttpModule到您的应用模块,只需导入AppHttpModule.
至于那个environment,你需要弄清楚的.使用angular-cli,当我们构建生产模式时,已经是一个自动切换到生产的环境.
这是我用来测试的完整示例
import { NgModule, Injector } from '@angular/core';
import { HttpModule, XHRBackend, BrowserXhr,
ResponseOptions, XSRFStrategy } from '@angular/http';
import { InMemoryBackendService, InMemoryDbService } from 'angular-in-memory-web-api';
let environment = {
production: true
};
export class MockData implements InMemoryDbService {
createDb() {
let cats = [
{ id: 1, name: 'Fluffy' }
];
return { cats };
}
}
@NgModule({
imports: [ HttpModule ],
providers: [
{
provide: XHRBackend,
useFactory: (injector: Injector, browser: BrowserXhr,
xsrf: XSRFStrategy, options: ResponseOptions): any => {
if (environment.production) {
return new XHRBackend(browser, options, xsrf);
} else {
return new InMemoryBackendService(injector, new MockData(), {});
}
},
deps: [ Injector, BrowserXhr, XSRFStrategy, ResponseOptions ]
}
]
})
export class AppHttpModule {
}
Run Code Online (Sandbox Code Playgroud)
voi*_*oid 24
见下文我的解决方案基于@peeskillet之一.
为您的示例创建一个模拟和实际服务实现的接口IHeroService.
export interface IHeroService {
getHeroes();
}
export class HeroService implements IHeroService {
getHeroes() {
//Implementation goes here
}
}
export class HeroMockService implements IHeroService {
getHeroes() {
//Mock implementation goes here
}
Run Code Online (Sandbox Code Playgroud)
假设您已使用Angular-CLI创建了Angular应用程序,请在您的environment.ts文件中添加适当的实现,例如:
import { HeroService } from '../app/hero.service';
export const environment = {
production: false,
heroService: HeroService
};
Run Code Online (Sandbox Code Playgroud)
对于每个不同的,environment.(prod|whatever).ts您必须定义heroService指向实现并添加导入.
现在,假设您要在AppModule类中导入服务(您可以在需要该服务的组件上执行此操作)
@NgModule({
declarations: [
AppComponent,
],
imports: [
FormsModule,
HttpModule,
AlertModule.forRoot()
],
providers: [
{
provide: 'IHeroService',
useClass: environment.heroService
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
重要的部分是提供者:
providers: [
{
provide: 'IHeroService',
useClass: environment.heroService
}
Run Code Online (Sandbox Code Playgroud)
现在,无论您想在何处使用该服务,都必须执行以下操作:
import { IHeroService } from './../hero.service';
export class HeroComponent {
constructor(@Inject('IHeroService') private heroService: IHeroService) {}
Run Code Online (Sandbox Code Playgroud)
来源: 是否可以使用angular2注入接口? https://medium.com/beautiful-angular/angular-2-and-environment-variables-59c57ba643be http://tattoocoder.com/angular-cli-using-the-environment-option/
如果将代码组织到Angular2模块中,则可以创建一个附加模块来导入模拟服务,例如:
@NgModule({
providers: [
{ provide: HeroService, useClass: HeroMockService }
]
})
export class MockModule {}
Run Code Online (Sandbox Code Playgroud)
假设您为核心模块中的普通服务声明导入:
@NgModule({
providers: [ HeroService ]
})
export class CoreModule {}
Run Code Online (Sandbox Code Playgroud)
只要你导入MockModule之后CoreModule,那么为HeroServicetoken 注入的值就是HeroMockService.这是因为如果同一令牌有两个提供程序,Angular将使用最新值.
然后,您可以MockModule根据特定值(表示构建环境)自定义导入,例如:
// Normal imported modules
var importedModules: Array<any> = [
CoreModule,
BrowserModule,
AppRoutingModule
];
if (process.env.ENV === 'mock') {
console.log('Enabling mocked services.');
importedModules.push(MockModule);
}
@NgModule({
imports: importedModules
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
这些答案中有许多是正确的,但无法通过摇树来解决。模拟服务将作为最终应用程序的一部分包含在内,而这通常是不需要的。此外,切换模拟模式并不容易。
我创建了一个解决这些问题的工作示例:https : //github.com/westonpace/angular-example-mock-services
useClass/ provide字段提供interface / abstract类)environment.*.ts文件中加载RealModule或MockModuleangular.json用于angular-cli创建新构建目标的mock文件,该目标将使用注入的模拟环境文件进行构建MockModule。创建一个新的serve配置来提供模拟构建,以便您可以这样做ng serve -c mock。更改默认量角器配置,以便它使用ng e2e模拟的服务目标,以便针对您的模拟服务运行。| 归档时间: |
|
| 查看次数: |
15282 次 |
| 最近记录: |