Typescript 定义全局常量

Typescript 定义全局常量,typescript,angular,Typescript,Angular,在Angular 1.x中,可以定义如下常量: export class CONSTANT { public static message2 = [ { "NAME_REQUIRED": "Name is required" } ] public static message = { "NAME_REQUIRED": "Name is required", } } import { Component, OnInit

在Angular 1.x中,可以定义如下常量:

export class CONSTANT {
    public static message2 = [
        { "NAME_REQUIRED": "Name is required" }
    ]

    public static message = {
        "NAME_REQUIRED": "Name is required",
    }
}
import { Component, OnInit                       } from '@angular/core';
import { CONSTANT                                } from '../../constants/dash-constant';


@Component({
  selector   : 'team-component',
  templateUrl: `../app/modules/dashboard/dashComponents/teamComponents/team.component.html`,
})

export class TeamComponent implements OnInit {
  constructor() {
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }

  ngOnInit() {
    console.log("oninit");
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }
}
angular.module('mainApp.config',[])
.constant('API_端点','http://127.0.0.1:6666/api/')
在Angular(带TypeScript)中,什么是等效的


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

只需使用一个Typescript常量即可

export var API_ENDPOINT = 'http://127.0.0.1:6666/api/';
您可以在依赖项注入器中使用

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

在Angular2中,您有以下定义,允许您设置不同类型的依赖项:

provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}
与角度1相比

Angular1中的
app.service
相当于Angular2中的
useClass

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

app.constant
app.value
已简化为
useValue
,约束更少。i、 e.不再有
config

app.provider
-Angular 2中没有等价物

示例

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)
      }),
declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment {
  API_URL: string;
  JWT_TOKEN_NAME: string;
}
'use strict';

export const dist = '../path/to/dist/';
import * as AppConst from '../app.const'; 

@Injectable()
export class AppService {

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

}
要使用根部喷射器进行设置,请执行以下操作:

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/'})]
或使用部件的喷油器进行设置:

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/'})]
provide
是以下内容的缩写:

var injectorValue = Injector.resolveAndCreate([
  new Provider(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})
]);
使用喷油器,很容易获得数值:

var endpoint = injectorValue.get(API_ENDPOINT);

以下更改适用于Angular 2最终版本:

export class AppSettings {
   public static API_ENDPOINT='http://127.0.0.1:6666/api/';
}
import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(AppSettings.API_ENDPOINT+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}
然后在服务中:

export class AppSettings {
   public static API_ENDPOINT='http://127.0.0.1:6666/api/';
}
import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(AppSettings.API_ENDPOINT+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}
从'angular2/Http'导入{Http};
从“../models/Message”导入{Message};
从'angular2/core'导入{Injectable};
从“rxjs/Observable”导入{Observable};
从“../AppSettings”导入{AppSettings};
导入'rxjs/add/operator/map';
@可注射()
导出类消息服务{
构造函数(私有http:http){}
getMessages():可观察{
返回此.http.get(AppSettings.API_ENDPOINT+/messages)
.map(response=>response.json())
.map((消息:Object[])=>{
returnmessages.map(message=>this.parseData(message));
});
}
私有数据(data):消息{
返回新消息(数据);
}
}

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

我们需要能够将这个api端点注入到我们的服务中(考虑将一个服务注入到另一个服务中)。我们也不需要为此创建一个完整的类,我们所要做的就是将一个字符串注入作为我们的端点的服务中。要完成,以下是有关如何在Angular 2中完成的完整代码:

首先,我们需要告诉Angular,当我们在应用程序中请求ApiEndpoint时,如何提供ApiEndpoint的实例(将其视为注册依赖项):


然后在服务中,我们将该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...
}
从'angular2/Http'导入{Http};
从“../models/Message”导入{Message};
从“angular2/core”导入{Injectable,injecte};//*我们在这里进口
从“rxjs/Observable”导入{Observable};
从“../AppSettings”导入{AppSettings};
导入'rxjs/add/operator/map';
@可注射()
导出类消息服务{
构造函数(私有http:http,
@注入('apidentpoint')私有apidentpoint:string){}
getMessages():可观察{
返回this.http.get(`${this.apidendpoint}/messages`)
.map(response=>response.json())
.map((消息:Object[])=>{
returnmessages.map(message=>this.parseData(message));
});
} 
//代码的其余部分。。。
}

使用生成过程中生成的属性文件既简单又容易。这是Angular CLI使用的方法。为每个环境定义属性文件,并在生成过程中使用命令确定将哪个文件复制到应用程序。然后只需导入要使用的属性文件

已为角度4更新+ 现在,我们可以简单地使用environments文件,如果您的项目是通过angular cli生成的,angular将提供默认文件

比如说

在您的环境文件夹中创建以下文件

  • environment.prod.ts
  • environment.qa.ts
  • environment.dev.ts
每个文件都可以保存相关的代码更改,例如:

  • environment.prod.ts

    export const environment = {
         production: true,
         apiHost: 'https://api.somedomain.com/prod/v1/',
         CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/qa/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/dev/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
  • environment.qa.ts

    export const environment = {
         production: true,
         apiHost: 'https://api.somedomain.com/prod/v1/',
         CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/qa/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/dev/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
  • environment.dev.ts

    export const environment = {
         production: true,
         apiHost: 'https://api.somedomain.com/prod/v1/',
         CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/qa/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/dev/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
    
应用中的用例 您可以将环境导入任何文件,如services
clientUtilServices.ts

从“../../environments/environment”导入{environment}

getHostURL(): string {
    return environment.apiHost;
  }
构建中的用例 打开angular cli文件
.angular cli.json
并在
中的“应用程序”:[{…}]
添加以下代码

 "apps":[{
        "environments": {
            "dev": "environments/environment.ts",
            "prod": "environments/environment.prod.ts",
            "qa": "environments/environment.qa.ts",
           }
         }
       ]
如果要为生产构建,请运行
ng build--env=prod
,它将从
environment.prod.ts
读取配置,与您为
qa
dev
执行此操作的方式相同

##老答案 在我的提供商中,我一直在做如下工作:

import {Injectable} from '@angular/core';

@Injectable()
export class ConstantService {

API_ENDPOINT :String;
CONSUMER_KEY : String;

constructor() {
    this.API_ENDPOINT = 'https://api.somedomain.com/v1/';
    this.CONSUMER_KEY = 'someReallyStupidTextWhichWeHumansCantRead'
  }
}
然后我可以在任何地方访问所有常量数据

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';

import {ConstantService} from  './constant-service'; //This is my Constant Service


@Injectable()
export class ImagesService {
    constructor(public http: Http, public ConstantService: ConstantService) {
    console.log('Hello ImagesService Provider');

    }

callSomeService() {

    console.log("API_ENDPOINT: ",this.ConstantService.API_ENDPOINT);
    console.log("CONSUMER_KEY: ",this.ConstantService.CONSUMER_KEY);
    var url = this.ConstantService.API_ENDPOINT;
    return this.http.get(url)
  }
 }

可以找到angular团队自己提供的配置解决方案

以下是所有相关代码:

1) app.config.ts

import { OpaqueToken } from "@angular/core";

export let APP_CONFIG = new OpaqueToken("app.config");

export interface IAppConfig {
    apiEndpoint: string;
}

export const AppConfig: IAppConfig = {    
    apiEndpoint: "http://localhost:15422/api/"    
};
2) app.module.ts

import { APP_CONFIG, AppConfig } from './app.config';

@NgModule({
    providers: [
        { provide: APP_CONFIG, useValue: AppConfig }
    ]
})
3) 你的服务

import { APP_CONFIG, IAppConfig } from './app.config';

@Injectable()
export class YourService {

    constructor(@Inject(APP_CONFIG) private config: IAppConfig) {
             // You can use config.apiEndpoint now
    }   
}
现在,您可以在任何地方插入配置,而无需使用字符串名称,也无需使用接口进行静态检查

当然,您可以进一步分离接口和常量,以便能够在生产和开发中提供不同的值,例如,如果您正在使用,我建议您可以为不同的环境设置常量。当你有不同的常数时,这是特别有价值的
export const environment = {
  production: false,
  apiUrl: 'http://localhost:8000/api/'
};
import { environment } from '../../environments/environment';
...
environment.apiUrl;
const api_endpoint = 'http://127.0.0.1:6666/api/';

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    MessageService,
    {provide: 'API_ENDPOINT', useValue: api_endpoint}
  ]
})
export class AppModule {
}
import {Injectable, Inject} from '@angular/core';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
      @Inject('API_ENDPOINT') private api_endpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(this.api_endpoint+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}
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
  }
}
{
    "baseUrl": "http://localhost:52555"
}
   {
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() {return setting.getSetting()},
      deps: [SettingService],
      multi: true
    }
// environments\ienvironments.ts

export class IEnvironment implements IEnvironmentParams {
  public production: boolean;
  public basicURL: string = 'https://www.someawesomedomain.com';
  public siteName: string = 'My awesome site';

  constructor(params: IEnvironmentParams) {
    this.production = params.production ?? false;
    this.basicURL = params.basicURL ?? this.basicURL;
    this.siteName = params.siteName ?? this.siteName;
  }
}

export interface IEnvironmentParams {
  production: boolean;
  basicURL?: string;
  siteName?: string;
}
// environments\environment.prod.ts

import {IEnvironment, IEnvironmentParams} from "./ienvironment";

const params: IEnvironmentParams = {
    production: true
};

export const environment: IEnvironment = new IEnvironment(params);
// environments\environment.ts

import {IEnvironment, IEnvironmentParams} from "./ienvironment";

const params: IEnvironmentParams = {
    production: false
};

export const environment: IEnvironment = new IEnvironment(params);
import {environment} from "../environments/environment";


// app-routing.module.ts

const routes: Routes = [
  { 
    path: '', component: HomeComponent,     
    data: {
        title: `${environment.siteName} | Home page title!`,
        description: 'some page description',
    }
  }
];
// home.component.ts

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent {

  constructor() {
    console.log(`home component constructor - showing evironment.siteName - ${environment.siteName}`);
  }
}