1. 程式人生 > >【轉載】在Angular 2/Typescript中聲明全局變量的最佳方式是什麽?

【轉載】在Angular 2/Typescript中聲明全局變量的最佳方式是什麽?

more 中一 keyword 訪問 emit 更新 other link 之間

問題詳細描述

我想在Typescript語言中的Angular 2中聲明一些全局可見的變量。最佳的實踐方法是?

推薦的實現方法

這是最簡單的解決方案,無需使用ServiceObserver

將全局變量放在文件中然後導出它們。

//
// ===== 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中聲明全局變量的最佳方式是什麽?