【轉載】在Angular 2/Typescript中聲明全局變量的最佳方式是什麽?
問題詳細描述
我想在Typescript
語言中的Angular 2
中聲明一些全局可見的變量。最佳的實踐方法是?
推薦的實現方法
這是最簡單的解決方案,無需使用Service
或Observer
:
將全局變量放在文件中然後導出它們。
//
// ===== File globals.ts
//
‘use strict‘;
export const sep=‘/‘;
export const version: string="22.2.2";
要在另一個文件中使用這些全局變量,請使用import
命令:import * as myGlobals from ‘./globals‘;
示例代碼:
//
// ===== File heroes.component.ts
//
import {Component, OnInit} from ‘angular2/core‘;
import {Router} from ‘angular2/router‘;
import {HeroService} from ‘./hero.service‘;
import {HeroDetailComponent} from ‘./hero-detail.component‘;
import {Hero} from ‘./hero‘;
import * as myGlobals from ‘./globals‘; //<==== this one
export class HeroesComponent implements OnInit {
public heroes: Hero[];
public selectedHero: Hero;
//
//
// Here we access the global var reference.
//
public helloString: string="hello " + myGlobals.sep + " there";
...
}
}
上述方法是最推薦的的解決方案,原因在於(1)代碼簡單並且代碼量少,(2)不需要你註入一些服務到每個單獨的組件或需要放置的地方,也不需要註冊。
對上面推薦解決方法的補充
上面提到的方法很不錯,不過這裏可以稍微改善一下。如果要導出包含所有常量的對象,可以簡單地使用es6import
模塊而不必使用require
。
另外,還可以使用Object.freeze
來使屬性成為真實的常量。如果對這個主題有進一步了解的興趣,可以閱讀這篇文章es6-const。
// global.ts
export const GlobalVariable = Object.freeze({
BASE_API_URL: ‘http://example.com/‘,
//... more of your variables
});
使用import
引用模塊。
//anotherfile.ts that refers to global constants
import { GlobalVariable } from ‘./path/global‘;
export class HeroService {
private baseApiUrl = GlobalVariable.BASE_API_URL;
//... more code
}
其他解決思路一
共享服務應該是最好的方法
export class SharedService {
globalVar:string;
}
但是,當需要在整個應用程序中共享同一個實例的時候,註冊時需要非常小心。在註冊應用程序時,需要定義它:
bootstrap(AppComponent, [SharedService]);
但不要在組件的providers
屬性中再次定義它:
@Component({
(...)
providers: [ SharedService ], // No
(...)
})
否則,將為該組件及其子組件創建一個新的服務實例。
參考關於依賴註入和分級註入器在Angular2中的工作原理的這個問題:
-
What‘s the best way to inject one service into another in angular 2 (Beta)?
可以註意到,當全局屬性需要更改時,還可以在服務中定義Observable
屬性以通知應用程序的部分:
export class SharedService {
globalVar:string;
globalVarUpdate:Observable<string>;
globalVarObserver:Observer;
constructor() {
this.globalVarUpdate = Observable.create((observer:Observer) => {
this.globalVarObserver = observer;
});
}
updateGlobalVar(newValue:string) {
this.globalVar = newValue;
this.globalVarObserver.next(this.globalVar);
}
}
更多細節,請參閱以下問題
-
Delegation: EventEmitter or Observable in Angular2
其他解決思路二
看一個例子Angular 2 - Implementation of shared services(Angular 2 共享服務的實現)
@Injectable()
class MyGlobals {
readonly myConfigValue:string = ‘abc‘;
}
@NgModule({
providers: [MyGlobals],
...
})
class MyComponent {
constructor(private myGlobals:MyGlobals) {
console.log(myGlobals.myConfigValue);
}
}
或提供單獨的值
@NgModule({
providers: [{provide: ‘myConfigValue‘, useValue: ‘abc‘}],
...
})
class MyComponent {
constructor(@Inject(‘myConfigValue‘) private myConfigValue:string) {
console.log(myConfigValue);
}
}
其他解決思路三
首先在app/globals.ts
中創建Globals
類:
import { Injectable } from ‘@angular/core‘;
Injectable()
export class Globals{
VAR1 = ‘value1‘;
VAR2 = ‘value2‘;
}
然後在組件中:
import { Globals } from ‘./globals‘;
@Component({
selector: ‘my-app‘,
providers: [ Globals ],
template: `<h1>My Component {{globals.VAR1}}<h1/>`
})
export class AppComponent {
constructor(private globals: Globals){
}
}
註意:您可以直接將Globals服務提供者添加到模塊而不是組件,您不需要為該模塊中的每個組件添加為提供者。
@NgModule({
imports: [...],
declarations: [...],
providers: [ Globals ],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
其他解決思路四
對於Angular2(v2.2.3)的IMHO,最好的方法是添加包含全局變量的服務,並將其註入到組件中,而不在@Component
註釋中使用providers
標記。通過這種方式,您可以在組件之間共享信息。
擁有全局變量的示例服務:
import { Injectable } from ‘@angular/core‘
@Injectable()
export class SomeSharedService {
public globalVar = ‘‘;
}
更新全局變量值的示例組件:
import { SomeSharedService } from ‘../services/index‘;
@Component({
templateUrl: ‘...‘
})
export class UpdatingComponent {
constructor(private someSharedService: SomeSharedService) { }
updateValue() {
this.someSharedService.globalVar = ‘updated value‘;
}
}
讀取全局變量值的示例組件:
import { SomeSharedService } from ‘../services/index‘;
@Component({
templateUrl: ‘...‘
})
export class ReadingComponent {
constructor(private someSharedService: SomeSharedService) { }
readValue() {
let valueReadOut = this.someSharedService.globalVar;
// do something with the value read out
}
}
請註意,
providers
:[SomeSharedService]
不應該添加到您的@Component
註解。通過不添加這個行註入,將始終能夠為您提供SomeSharedService
的相同實例。如果添加行,則會註入新創建的實例。
補充解決思路一
這不一定是最好的方法,但是如果要在組件中定義全局變量,最簡單的方法是使用window
變量來寫入:
window.GlobalVariable = "what ever!"
您不需要將其傳遞給引導或導入其他位置,它就可以全局訪問所有JS(不僅有angular 2組件)。
補充解決思路二
算是對最推薦方法的補充,使用const關鍵字,就像在ES6中一樣:
//
// ===== File globals.ts
//
‘use strict‘;
export const sep=‘/‘;
export const version: string="22.2.2";
補充解決思路三
如下代碼所示的方式:
global.ts
export var server: string = ‘http://localhost:4200/‘;
export var var2 : number = 2;
export var var3 : string = ‘var3‘;
使用它只需要像這樣導入:
import {Injectable} from "@angular/core";
import {Http, Headers, RequestOptions} from "@angular/http";
import {Observable} from "rxjs/Rx";
import * as glob from "../shared/global"; //<== HERE
@Injectable()
export class AuthService {
private AuhtorizationServer = glob.server
}
【轉載】在Angular 2/Typescript中聲明全局變量的最佳方式是什麽?