web-dev-qa-db-fra.com

Comment déclarer une variable globale dans Angular 2 / Typescript?

Je voudrais que certaines variables soient accessibles partout dans un Angular 2 dans le langage TypeScript. Comment dois-je m'y prendre pour accomplir cela?

151
supercobra

Voici la solution la plus simple sans Service ni Observer:

Placez les variables globales dans un fichier et exportez-les.

//
// ===== File globals.ts    
//
'use strict';

export const sep='/';
export const version: string="22.2.2";    

Pour utiliser des éléments globaux dans un autre fichier, utilisez une instruction import: import * as myGlobals from './globals';

Exemple:

// 
// ===== 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";

         ...

        }
    }

Merci @ eric-martinez

180
supercobra

J'aime aussi la solution de @supercobra. Je voudrais juste l'améliorer légèrement. Si vous exportez un objet contenant toutes les constantes, vous pouvez simplement utiliser es6 . Importer le module sans utiliser require .

J'ai également utilisé Object.freeze pour que les propriétés deviennent de vraies constantes. Si le sujet vous intéresse, vous pouvez lire ceci post .

// global.ts

 export const GlobalVariable = Object.freeze({
     BASE_API_URL: 'http://example.com/',
     //... more of your variables
 });

Référez-vous au module en utilisant import.

//anotherfile.ts that refers to global constants
import { GlobalVariable } from './path/global';

export class HeroService {
    private baseApiUrl = GlobalVariable.BASE_API_URL;

    //... more code
}
84
Tim Hong

Un service partagé est la meilleure approche

export class SharedService {
  globalVar:string;
}

Mais vous devez être très prudent lors de son enregistrement pour pouvoir partager une seule instance pour l'ensemble de votre application. Vous devez le définir lors de l’enregistrement de votre application:

bootstrap(AppComponent, [SharedService]);

mais ne le redéfinissez pas dans les attributs providers de vos composants:

@Component({
  (...)
  providers: [ SharedService ], // No
  (...)
})

Sinon, une nouvelle instance de votre service sera créée pour le composant et ses sous-composants.

Vous pouvez consulter cette question sur le fonctionnement de l'injection de dépendance et des injecteurs hiérarchiques dans Angular2:

Vous pouvez également noter que vous pouvez également définir des propriétés Observable dans le service afin de notifier des parties de votre application lorsque vos propriétés globales changent:

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);
  }
}

Voir cette question pour plus de détails:

52
Thierry Templier

Voir par exemple Angular 2 - Implémentation de services partagés

@Injectable() 
export class MyGlobals {
  readonly myConfigValue:string = 'abc';
}

@NgModule({
  providers: [MyGlobals],
  ...
})

class MyComponent {
  constructor(private myGlobals:MyGlobals) {
    console.log(myGlobals.myConfigValue);
  }
}

ou fournir des valeurs individuelles

@NgModule({
  providers: [{provide: 'myConfigValue', useValue: 'abc'}],
  ...
})

class MyComponent {
  constructor(@Inject('myConfigValue') private myConfigValue:string) {
    console.log(myConfigValue);
  }
}
37
Günter Zöchbauer

Créez la classe Globals dans app/globals.ts:

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

Injectable()
export class Globals{
    VAR1 = 'value1';
    VAR2 = 'value2';
}

Dans votre composant:

import { Globals } from './globals';

@Component({
    selector: 'my-app',
    providers: [ Globals ],
    template: `<h1>My Component {{globals.VAR1}}<h1/>`
})
export class AppComponent {
    constructor(private globals: Globals){
    }
}

Remarque: Vous pouvez ajouter le fournisseur de services Globals directement au module à la place du composant. Vous n'aurez pas besoin de l'ajouter en tant que fournisseur à chaque composant de ce module.

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [ Globals ],
    bootstrap: [ AppComponent ]
})
export class AppModule {
}
15
gradosevic

IMHO pour Angular2 (v2.2.3) le meilleur moyen est d'ajouter des services contenant la variable globale et de les injecter dans des composants sans la balise providers à l'intérieur de l'annotation @Component. De cette façon, vous pouvez partager des informations entre les composants.

Un exemple de service qui possède une variable globale:

import { Injectable } from '@angular/core'

@Injectable()
export class SomeSharedService {
  public globalVar = '';
}

Un exemple de composant qui met à jour la valeur de votre variable globale:

import { SomeSharedService } from '../services/index';

@Component({
  templateUrl: '...'
})
export class UpdatingComponent {

  constructor(private someSharedService: SomeSharedService) { }

  updateValue() {
    this.someSharedService.globalVar = 'updated value';
  }
}

Un exemple de composant qui lit la valeur de votre variable globale:

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
  }
}

Notez que providers: [ SomeSharedService ] devrait ne pas être ajouté à votre annotation @Component. En n’ajoutant pas cette injection de ligne, vous obtiendrez toujours la même instance de SomeSharedService. Si vous ajoutez la ligne, une instance fraîchement créée est injectée.

11
Timo Bähr

Je ne connais pas le meilleur moyen, mais le moyen le plus simple de définir une variable globale dans un composant consiste à utiliser la variable window pour écrire comme suit:

window.GlobalVariable = "what ever!"

vous n'avez pas besoin de le passer à bootstrap ni de l'importer ailleurs, et il est globalement accessible à tous les composants JS (pas uniquement angular 2 composants).

8
Mahdi Jadaliha

C'est comme ça que je l'utilise:

global.ts

export var server: string = 'http://localhost:4200/';
export var var2: number = 2;
export var var3: string = 'var3';

pour l'utiliser importez simplement comme ça:

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
}

EDITED: Supprimé "_" avec le préfixe recommandé.

5
Guilherme Teubl

Je pense que le meilleur moyen est de partager un objet avec des variables globales dans votre application en l'exportant et en l'important où vous le souhaitez.

Commencez par créer un nouveau fichier . Ts par exemple globals.ts et déclarez-le. un objet. Je lui ai donné un type Object mais vous pouvez également utiliser un tout type ou {}

export let globalVariables: Object = {
 version: '1.3.3.7',
 author: '0x1ad2',
 everything: 42
};

Après cette importation

import {globalVariables} from "path/to/your/globals.ts"

Et l'utiliser

console.log(globalVariables);
4
0x1ad2

J'aime la réponse de @supercobra, mais j'utiliserais le mot clé const tel qu'il est déjà disponible dans ES6:

//
// ===== File globals.ts    
//
'use strict';

export const sep='/';
export const version: string="22.2.2"; 
3
Zolcsi