在Angular 1中。X你可以这样定义常量:
angular.module('mainApp.config', [])
.constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')
在Angular中(使用TypeScript)会是什么?
我只是不想在我的所有服务中一遍又一遍地重复API基url。
在Angular 1中。X你可以这样定义常量:
angular.module('mainApp.config', [])
.constant('API_ENDPOINT', '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/'}), ...]);
其他回答
为Angular 4+更新
现在,如果你的项目是通过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' ], }; environment.qa.ts export const environment = { production: false, apiHost: 'https://api.somedomain.com/qa/v1/', CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', codes: [ 'AB', 'AC', 'XYZ' ], }; environment.dev.ts export const environment = { production: false, apiHost: 'https://api.somedomain.com/dev/v1/', CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', codes: [ 'AB', 'AC', 'XYZ' ], };
应用程序中的用例
您可以将环境导入到任何文件中,例如服务clientUtilServices.ts
从'../../environments/environment'导入{environment};
getHostURL(): string {
return environment.apiHost;
}
构建中的用例
打开你的angular cli文件。angular-cli。Json和“apps”内部:[{…}]添加以下代码
"apps":[{
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts",
"qa": "environments/environment.qa.ts",
}
}
]
如果你想在生产环境中构建,运行ng build——env=prod,它会从environment. product .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)
}
}
如果你正在使用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)});
}
AngularJS的模块。Constant不能定义标准意义上的常数。
虽然它是一个独立的提供者注册机制,但是最好在相关模块的上下文中理解它。Value ($ provider . Value)函数。官方文档清楚地陈述了用例:
用$injector注册一个值服务,比如一个字符串、一个数字、一个数组、一个对象或一个函数。这是注册服务的缩写,其中其提供者的$get属性是一个不接受参数并返回值服务的工厂函数。这也意味着不可能将其他服务注入到价值服务中。
将其与模块的文档进行比较。常量($ provider . Constant),它也清楚地说明了用例(强调我的):
用$injector注册一个常量服务,比如一个字符串、一个数字、一个数组、一个对象或一个函数。与值一样,不可能将其他服务注入到常量中。 但与value不同的是,常量可以被注入到模块的配置函数中(参见angular.Module),而且它不能被AngularJS的装饰器覆盖。
因此,AngularJS的constant函数并没有在这个领域中提供一个通常理解的常量。
也就是说,对所提供的对象施加的限制,以及它之前通过$注入器的可用性,清楚地表明该名称是类推使用的。
如果你想在AngularJS应用程序中有一个实际的常量,你可以像在任何JavaScript程序中一样“提供”一个
export const π = 3.14159265;
在Angular 2中,同样的技术也适用。
Angular 2应用程序没有AngularJS应用程序那样的配置阶段。此外,没有服务装饰器机制(AngularJS decorator),但考虑到它们彼此之间的差异,这并不特别令人惊讶。
例如
angular
.module('mainApp.config', [])
.constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');
是模糊任意的,有点令人讨厌,因为$ provider。Constant被用来指定一个对象,这个对象碰巧也是一个常量。你还不如写信算了
export const apiEndpoint = 'http://127.0.0.1:6666/api/';
因为任何一方都可以改变。
现在关于可测性的争论,嘲笑常数,被削弱了,因为它字面上是不变的。
不模拟π。
当然,您的应用程序特定的语义可能是您的端点可能会更改,或者您的API可能具有非透明的故障转移机制,因此API端点在某些情况下更改是合理的。
但在这种情况下,将其作为单个URL的字符串文字表示提供给常量函数是行不通的。
一个更好的参数,可能更符合AngularJS $ provider存在的原因。常量函数是,当AngularJS被引入时,JavaScript还没有标准的模块概念。在这种情况下,全局变量将用于共享可变或不可变的值,使用全局变量是有问题的。
也就是说,通过框架提供这样的东西可以增加与该框架的耦合。它还将特定于Angular的逻辑与适用于任何其他系统的逻辑混合在一起。
这并不是说这是一种错误或有害的方法,但就我个人而言,如果我想在Angular 2应用程序中使用常量,我会写
export const π = 3.14159265;
就像我使用AngularJS一样。
事情改变得越多……
在Angular 4中,你可以使用环境类来保存所有的全局变量。
你有环境。Ts和environment. products . Ts。
例如
export const environment = {
production: false,
apiUrl: 'http://localhost:8000/api/'
};
在你的服务中:
import { environment } from '../../environments/environment';
...
environment.apiUrl;
虽然有一个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...
}