Cuál es la mejor manera de declarar una variable global en Angular 2 / Typescript [cerrado]


Me gustaría que algunas variables sean accesibles en todas partes en un Angular 2 en el lenguaje Typescript. ¿Cuál es la mejor manera de hacer esto?

Author: vusan, 2016-03-22

10 answers

Aquí está la solución más simple w/o Service ni Observer:

Coloque las variables globales en un archivo y expórtelas.

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

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

Para usar globals en otro archivo use una instrucción import : import * as myGlobals from './globals';

Ejemplo:

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

         ...

        }
    }

Gracias @ eric-martinez

 155
Author: supercobra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-06 05:13:36

También me gusta la solución de @supercobra. Solo me gustaría mejorarlo un poco. Si exporta un objeto que contiene todas las constantes, simplemente podría usar es6 importarel módulo sin usar requerir.

También utilicé Object.congelar para que las propiedades se conviertan en constantes verdaderas. Si estás interesado en el tema, puedes leer este post .

// global.ts

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

Consulte el módulo usando import.

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

export class HeroService {
    private baseApiUrl = GlobalVariable.BASE_API_URL;

    //... more code
}
 74
Author: Tim Hong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-02 03:38:08

Un servicio compartido es el mejor enfoque

export class SharedService {
  globalVar:string;
}

Pero debe tener mucho cuidado al registrarlo para poder compartir una sola instancia para toda su aplicación. Debe definirlo al registrar su solicitud:

bootstrap(AppComponent, [SharedService]);

Pero no volver a definirlo dentro de los atributos providers de tus componentes:

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

De lo contrario, se creará una nueva instancia de su servicio para el componente y sus subcomponentes.

Puedes echar un vistazo a esta pregunta en cuanto a cómo funcionan la inyección de dependencia y los inyectores jerárquicos en Angular2:

Puede notar que también puede definir Observable propiedades en el servicio para notificar partes de su aplicación cuando sus propiedades globales cambian:

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

Vea esta pregunta para más detalles:

 47
Author: Thierry Templier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:36

Ver por ejemplo Angular 2-Implementación de servicios compartidos

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

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

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

O proporcionar valores individuales

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

class MyComponent {
  constructor(@Inject('myConfigValue') private myConfigValue:string) {
    console.log(myConfigValue);
  }
}
 29
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-15 14:46:45

Crea la clase Globals en app/globals.ts :

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

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

En tu componente:

import { Globals } from './globals';

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

Nota : Puede agregar Globals service provider directamente al módulo en lugar del componente, y no necesitará agregar como proveedor a cada componente en ese módulo.

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [ Globals ],
    bootstrap: [ AppComponent ]
})
export class AppModule {
}
 13
Author: gradosevic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-09 18:28:31

IMHO para Angular2 (v2.2.3) la mejor manera es agregar servicios que contengan la variable global e inyectarlos en componentes sin la etiqueta providers dentro de la anotación @Component. De esta manera usted es capaz de compartir información entre los componentes.

Un servicio de ejemplo que posee una variable global:

import { Injectable } from '@angular/core'

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

Un componente de muestra que actualiza el valor de su variable global:

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

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

  constructor(private someSharedService: SomeSharedService) { }

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

Un componente de muestra que lee el valor de su variable:

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

Note que providers: [ SomeSharedService ]debería no ser agregado a su anotación @Component. Al no agregar esta inyección de línea siempre le dará la misma instancia de SomeSharedService. Si agrega la línea, se inyecta una instancia recién creada.

 10
Author: Timo Bähr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-23 14:55:30

No conozco la mejor manera, pero la forma más fácil si quieres definir una variable global dentro de un componente es usar window variable para escribir así:

window.GlobalVariable = "what ever!"

No es necesario pasarlo a bootstrap o importarlo a otros lugares, y es globalmente accesible a todos los JS (no solo a los componentes de angular 2).

 6
Author: Mahdi Jadaliha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-30 17:16:54

Esa es la forma en que lo uso:

Global.ts

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

Para usarlo solo importa así:

  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
        }

EDITADO: Droped " _ " prefijado como se recomienda.

 4
Author: Guilherme Teubl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-04 15:30:44

Creo que la mejor manera es compartir un objeto con variables globales a lo largo de su aplicación exportándolo e importándolo donde desee.

Primero crea un nuevo .archivo ts por ejemplo globals.ts y declarar un objeto. Le di un tipo Object pero también podría usar un cualquier tipo o {}

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

Después de importarlo

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

Y usarlo

console.log(globalVariables);
 4
Author: 0x1ad2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:26

Me gusta la respuesta de @supercobra, pero usaría la palabra clave const tal como está en ES6 ya disponible:

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

export const sep='/';
export const version: string="22.2.2"; 
 3
Author: Zolcsi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 11:50:23