Angular 5根据环境提供http拦截器

时间:2017-11-02 10:01:57

标签: javascript angular angular-http-interceptors

我的angular-cli(v1.5.1,angular v5)应用程序中有以下两种环境:

  1. dev的
  2. Dev使用模拟数据,我提供了一个http拦截器。 Pro使用实时休息api。

    如何在dev上提供http-interceptor,而不是在pro上提供? 我已经尝试了以下内容,但它不起作用:

    {
      provide: HTTP_INTERCEPTORS,
      useFactory: () => {
        if (environment.useMockBackend === true) {
          return MockHttpInterceptor;
        }
        return false;
      },
      multi: true
    }
    

3 个答案:

答案 0 :(得分:4)

在我的Angular 5.2项目中,我使用了以下方法。

<强> app.module.ts

// How to use: Any Widget in the app can access the ThemeChanger
// because it is an InheritedWidget. Then the Widget can call
// themeChanger.theme = [blah] to change the theme. The ThemeChanger
// then accesses AppThemeState by using the _themeGlobalKey, and
// the ThemeChanger switches out the old ThemeData for the new
// ThemeData in the AppThemeState (which causes a re-render).

final _themeGlobalKey = new GlobalKey(debugLabel: 'app_theme');

class AppTheme extends StatefulWidget {

  final child;

  AppTheme({
    this.child,
  }) : super(key: _themeGlobalKey);

  @override
  AppThemeState createState() => new AppThemeState();
}

class AppThemeState extends State<AppTheme> {

  ThemeData _theme = DEV_THEME;

  set theme(newTheme) {
    if (newTheme != _theme) {
      setState(() => _theme = newTheme);
    }
  }

  @override
  Widget build(BuildContext context) {
    return new ThemeChanger(
      appThemeKey: _themeGlobalKey,
      child: new Theme(
        data: _theme,
        child: widget.child,
      ),
    );
  }
}

class ThemeChanger extends InheritedWidget {

  static ThemeChanger of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(ThemeChanger);
  }

  final ThemeData theme;
  final GlobalKey _appThemeKey;

  ThemeChanger({
    appThemeKey,
    this.theme,
    child
  }) : _appThemeKey = appThemeKey, super(child: child);

  set appTheme(AppThemeOption theme) {
    switch (theme) {
      case AppThemeOption.experimental:
        (_appThemeKey.currentState as AppThemeState)?.theme = EXPERIMENT_THEME;
        break;
      case AppThemeOption.dev:
        (_appThemeKey.currentState as AppThemeState)?.theme = DEV_THEME;
        break;
    }
  }

  @override
  bool updateShouldNotify(ThemeChanger oldWidget) {
    return oldWidget.theme == theme;
  }

}

<强> my.interceptor.ts

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { environment } from '../environments/environment';
import { MyInterceptor } from './my.interceptor';

const commonProviders = [/*...*/];
const nonProductionProviders = [{ 
  provide: HTTP_INTERCEPTORS,
  useClass: MyInterceptor,
  multi: true
}];

@NgModule({
  imports: [
    HttpClientModule,
    // ...
  ],
  providers: [
    ...commonProviders,
    ...!environment.production ? nonProductionProviders : []
  ]
})

答案 1 :(得分:1)

这个想法是从环境文件,prod环境导出do-nothing拦截器或只是任何其他虚拟提供程序(让它命名为DefaultHttpInterceptor)和dev导出MockHttpInterceptor来导出拦截器提供程序。

开发环境:export const INTERCEPTORS = {provide: HTTP_INTERCEPTORS, ... MockHttpInterceptor}

生产环境:export const INTERCEPTORS = {provide: HTTP_INTERCEPTORS, ... DefaultHttpInterceptor}

然后你可以像往常一样使用它:

import { INTERCEPTORS } from './../environments/environment';
@NgModule({
providers      : [
        ...
        INTERCEPTORS 
        ...
    ]
...
})

答案 2 :(得分:0)

我通过借鉴@dhilt和@kemsky的先前答案,提出了以下方法(在Angular 7中):

您的开发环境文件

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MyDevInterceptor} from './my-dev.interceptor';

export const ENVIRONMENT_SPECIFIC_PROVIDERS = [
  { provide: HTTP_INTERCEPTORS, useClass: MyDevInterceptor, multi: true }
];

environment.prod.ts

export const ENVIRONMENT_SPECIFIC_PROVIDERS = [];

app.module.ts

@NgModule({
  declarations: [],
  imports: [
    HttpClientModule
  ],
  providers: [
    ENVIRONMENT_SPECIFIC_PROVIDERS
  ]
})

这很简单,可以很好地对待您,这意味着您的代码库不包含对您的环境不需要的任何内容的引用。