如何在Angular2中基于特定的构建环境注入不同的服务? [英] How to inject different service based on certain build environment in Angular2?

查看:35
本文介绍了如何在Angular2中基于特定的构建环境注入不同的服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有HeroMockService将返回模拟数据,而HeroService将调用后端服务以从数据库中检索英雄.

I have HeroMockService that will return mocked data and HeroService that will call back end service to retrieve heroes from database.

假设Angular2具有构建环境,如果当前构建环境为"dev-mock",我打算将<​​c0>注入到AppComponent中.如果当前的构建环境是"dev-rest",则应该将HeroService注入到AppComponent.

Assuming Angular2 has build environment, I'm planning to inject HeroMockService to AppComponent if current build environment is "dev-mock". If current build environment is "dev-rest", HeroService should be injected to AppComponent instead.

我想知道如何实现这一目标?

I would like to know how can I achieve this?

推荐答案

IMO,更好的选择是使用内存中的角度网络API .它模拟了Http所使用的后端,因此,它没有进行实际的XHR调用,而是仅获取您提供给它的数据.要获取它,只需安装

IMO, a better option would be to use the angular-in-memory-web-api. It mocks the backend that Http uses, so instead of making an actual XHR call, it just grabs the data that you provide to it. To get it, just install

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

要创建数据库,请在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 };
}

然后配置它

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.

Now when you use Http and make a request to /api/cats it will get all the cats from the db. If you go to /api/cats/1 it will get the first cat. You can do all the CRUD operations, GET, POST, PUT, DELETE.

要注意的一件事是它需要基本路径.在示例中,/api是基本路径.您还可以在配置中配置根(与基本路径不同)路径

One thing to note is that it expects a base path. In the example /api is the base path. You can also configure a root (this is different from base) path, in the configuration

InMemoryWebApiModule.forRoot(MockData, {
  rootPath: 'root',
  passThruUnknownUrl: true // forwards request not in the db
})

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

关于如何从开发人员转换为生产人员的问题,您可以使用工厂来创建提供程序.如果您要使用模拟服务而不是in-memory-web-api

In regards to the question about how to switch from dev to production, you can use a factory to create the providers. Same would be true if you were to use your mock service instead of the 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 ]
]

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

As far as the in-memory-web-api, I need to get back to you (I need to test a theory). I just started using it, and haven't gotten to the point where I need to switch to production. Right now I just have the above configuration. But I'm sure there's a way to make it work without having to change anything

好吧,对于im-memory-web-api,我们可以做的是导入模块提供的XHRBackend,而不是导入模块. XHRBackendHttp用于进行XHR调用的服务.内存中的wep-api模拟了该服务.这就是模块要做的所有事情.因此,我们可以使用工厂自己提供服务

Ok so for the im-memory-web-api what we can do instead of importing the Module, is to just provide the XHRBackend that the module provides. The XHRBackend is the service that Http uses to make XHR calls. The in-memory-wep-api mocks that service. That's all the module does. So we can just provide the service ourselves, using a factory

@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.

Notice the BrowserXhr, XSRFStrategy, and ResponseOptions dependencies. This is how the original XHRBackend is created. Now instead of importing the HttpModule into your app module, just import the AppHttpModule.

environment而言,这是您需要弄清楚的.有了angular-cli,当我们在生产模式下构建时,已经是一个可以自动切换到生产环境.

As far as the environment, that's something you need to figure out. With angular-cli, the is already an environment that gets automatically switched to production when we build in production mode.

这是我用来测试的完整示例

Here's the complete example I used to test with

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

这篇关于如何在Angular2中基于特定的构建环境注入不同的服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆