我想在 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
- }
来源: http://www.bubuko.com/infodetail-2435012.html