在Angular 1中。X你可以这样定义常量:

angular.module('mainApp.config', [])
    .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')

在Angular中(使用TypeScript)会是什么?

我只是不想在我的所有服务中一遍又一遍地重复API基url。


当前回答

所有的解决方案似乎都很复杂。我在寻找这种情况下最简单的解我只想用常数。常量很简单。是否有反对以下解决方案的意见?

app.const.ts

'use strict';

export const dist = '../path/to/dist/';

app.service.ts

import * as AppConst from '../app.const'; 

@Injectable()
export class AppService {

    constructor (
    ) {
        console.log('dist path', AppConst.dist );
    }

}

其他回答

在Angular2中,你有以下提供定义,它允许你设置不同类型的依赖:

provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}

与Angular 1的比较

在Angular1中,app.service等价于Angular2中的useClass。

Angular1中的app.factory相当于Angular2中的useFactory。

app.constant和app.value被简化为useValue,约束更少。也就是说,不再有配置块了。

app.provider——在Angular 2中没有等价的。

例子

使用根注入器进行设置:

bootstrap(AppComponent,[provide(API_ENDPOINT, { useValue='http://127.0.0.1:6666/api/' })]);

或者使用组件的注入器进行设置:

providers: [provide(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})]

提供是对…的简称:

var injectorValue = Injector.resolveAndCreate([
  new Provider(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})
]);

使用注入器,获取值很容易:

var endpoint = injectorValue.get(API_ENDPOINT);

虽然有一个AppSettings类和一个字符串常量作为ApiEndpoint的方法是可行的,但这并不理想,因为我们不能在单元测试时将这个真正的ApiEndpoint交换为其他一些值。

我们需要能够将这个api端点注入到我们的服务中(想象一下将一个服务注入到另一个服务中)。我们也不需要为此创建一个完整的类,我们所要做的只是将一个字符串注入到我们的服务中,作为我们的ApiEndpoint。为了完成这个完美的答案,下面是在Angular 2中如何完成的完整代码:

首先,我们需要告诉Angular,当我们在应用中请求ApiEndpoint时,如何提供它的实例(把它看作是注册一个依赖):

bootstrap(AppComponent, [
        HTTP_PROVIDERS,
        provide('ApiEndpoint', {useValue: 'http://127.0.0.1:6666/api/'})
]);         

然后在服务中,我们将这个ApiEndpoint注入到服务的构造函数中,Angular会根据我们上面的注册为我们提供它:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable, Inject} from 'angular2/core';  // * We import Inject here
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
                @Inject('ApiEndpoint') private apiEndpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(`${this.apiEndpoint}/messages`)
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    } 
    // the rest of the code...
}

以下是我最近在这种情况下的经验:

@angular / cli: 1.0.0 节点:6.10.2 @angular /核心:4.0.0

我在这里遵循了官方和更新的文档:

https://angular.io/docs/ts/latest/guide/dependency-injection.html !# dependency-injection-tokens

似乎OpaqueToken现在已弃用,我们必须使用InjectionToken,所以这些是我的文件运行起来像一个魅力:

app-config.interface.ts

export interface IAppConfig {

  STORE_KEY: string;

}

app-config.constants.ts

import { InjectionToken } from "@angular/core";
import { IAppConfig } from "./app-config.interface";

export const APP_DI_CONFIG: IAppConfig = {

  STORE_KEY: 'l@_list@'

};

export let APP_CONFIG = new InjectionToken< IAppConfig >( 'app.config' );

app.module.ts

import { APP_CONFIG, APP_DI_CONFIG } from "./app-config/app-config.constants";

@NgModule( {
  declarations: [ ... ],
  imports: [ ... ],
  providers: [
    ...,
    {
      provide: APP_CONFIG,
      useValue: APP_DI_CONFIG
    }
  ],
  bootstrap: [ ... ]
} )
export class AppModule {}

my-service.service.ts

  constructor( ...,
               @Inject( APP_CONFIG ) private config: IAppConfig) {

    console.log("This is the App's Key: ", this.config.STORE_KEY);
    //> This is the App's Key:  l@_list@

  }

结果是干净的,主机上没有任何警告,这要感谢John Papa最近在这个问题上的评论:

https://github.com/angular/angular-cli/issues/2034

该键在接口的另一个文件中实现。

如果你正在使用Webpack(我推荐使用Webpack),你可以为不同的环境设置常量。当每个环境都有不同的常数值时,这一点尤其有价值。

在你的/config目录下可能有多个webpack文件(例如,webpack.dev.js, webpack.prod.js等)。然后你会有一个custom- types .d。把t加在这里。下面是每个文件中要遵循的一般模式,以及组件中的示例用法。

网络包。{env}.js

const API_URL = process.env.API_URL = 'http://localhost:3000/';
const JWT_TOKEN_NAME = "id_token";
...
    plugins: [
      // NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
      new DefinePlugin({
        'API_URL': JSON.stringify(API_URL),
        'JWT_TOKEN_NAME': JSON.stringify(JWT_TOKEN_NAME)
      }),

custom-typings.d.ts

declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment {
  API_URL: string;
  JWT_TOKEN_NAME: string;
}

组件

export class HomeComponent implements OnInit {
  api_url:string = API_URL;
  authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME)});
}

我有另一种定义全局常数的方法。因为如果我们在ts文件中定义,如果在生产模式中构建,就不容易找到常数来改变值。

export class SettingService  {

  constructor(private http: HttpClient) {

  }

  public getJSON(file): Observable<any> {
      return this.http.get("./assets/configs/" + file + ".json");
  }
  public getSetting(){
      // use setting here
  }
}

在app文件夹中,我添加文件夹configs/setting.json

设置.json中的内容

{
    "baseUrl": "http://localhost:52555"
}

在app模块中添加APP_INITIALIZER

   {
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() {return setting.getSetting()},
      deps: [SettingService],
      multi: true
    }

通过这种方式,我可以更容易地更改json文件中的值。 我还将这种方法用于常量错误/警告消息。