如何在Angular2中基于特定的构建环境注入不同的服务?

新手:

HeroMockService将返回模拟数据HeroService,并调用后端服务从数据库中检索英雄。

假设Angular2有编译环境,我打算注入HeroMockServiceAppComponent如果当前构建环境"dev-mock"如果当前的构建环境为"dev-rest"HeroService则应注入AppComponent

我想知道如何实现?

保罗·萨姆索塔(Paul Samsotha):

IMO,更好的选择是使用angular-in-memory-web-api它模拟了所Http使用的后端,因此,它无需进行实际的XHR调用,而只是获取您提供给它的数据。要获得它,只需安装

npm install --save angular-in-memory-web-api

要创建数据库,您可以createDbInMemoryDbService

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 };
}

然后配置它

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';

@NgModule({
  imports: [
    HttpModule,
    InMemoryWebApiModule.forRoot(MockData, {
      passThruUnknownUrl: true
    }),
  ]
})

现在,当您使用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
})

现在您可以使用了/root/api/cats


更新

关于如何从开发人员转换为生产人员的问题,您可以使用工厂来创建提供程序。如果您要使用模拟服务而不是in-memory-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 ]
]

至于内存中的网络api,我需要回复您(我需要测试一种理论)。我只是开始使用它,还没有到达需要转为生产的地步。现在,我只有上面的配置。但是我敢肯定,有一种方法可以使它工作而无需更改任何内容

更新2

好的,对于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 {
}

请注意BrowserXhrXSRFStrategyResponseOptions依赖。这就是原始文件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 {
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在基于服务的Angular2项目中使用依赖注入

在Angular2中,如何将不同的数据服务注入到每个组件中

如何在Angular2中构建可部署的Web服务器版本?

如何在Angular 2应用中配置不同的开发环境

带有angular-cli的angular2中的特定于环境的服务端点

Angular2:注入服务

将服务注入angular2中的服务

如何在Angular2中订阅服务上的事件?

如何在Angular2中监视服务呼叫

如何在Angular2中强制刷新Observable服务?

在Angular2中,如何使用注入服务中的值设置静态变量?

如何在不同的环境中构建角度项目

Angular 2 CLI中基于环境的不同代理配置

如何在Angular2中注入相同组件的新实例

如何在Angular2中正确使用依赖注入(DI)?

如何在Angular2中正确使用依赖项注入?

如何在Angular2中注入间接祖先组件

Angular2简单的Http服务注入

如何在Angular2对象数组中基于属性值进行过滤?

如何在Typescript / Angular2中显示基于[用户位置]的日期格式

如何在Angular 2中添加服务并在注入时出错?

如何在Angular.js中配置不同的环境?

如何在angular2中路由不同的组件或页面

如何在angular2中的不同条件下选择checbox

如何从行动注入Angular 2服务中的提供者?

如何在Angular2中的模块加载上实例化单例服务

如何在Angular2中向服务器提交表单?

如何在 angular2 的不同模块中使用自定义错误处理程序服务

如何在 Angular Dart 中构建 HttpInterceptor 服务?