Como posso declarar uma variável global no Angular 2 em diante/Typescript?
Eu gostaria que algumas variáveis fossem acessíveis em todo lugar em um Angular 2 na linguagem Typescript. Como devo proceder para realizar isso?
Resposta #1
Aqui está a solução mais simples sem Service ou Observer:
Coloque as variáveis globais em um arquivo e exporte-as.
//
// ===== File globals.ts
//
'use strict';
export const sep='/';
export const version: string="22.2.2";
Para usar globals em outro arquivo, use uma instrução import: import * as myGlobals from 'globals';
Exemplo :
//
// ===== 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 (**Updated**)
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";
...
}
}
Resposta #2
Eu gosto da solução do @supercobra também. Eu só gostaria de melhorá-la um pouco. Se você exportar um objeto que contém todas as constantes, você poderia simplesmente usar es6 import do módulo sem usar require.
Eu também usei Object.freeze para fazer com que as propriedades se tornassem constantes verdadeiras. Se você estiver interessado no assunto, você poderia ler este post.
// global.ts
export const GlobalVariable = Object.freeze({
BASE_API_URL: 'http://example.com/',
//... more of your variables
});
Referencie o 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
}
Resposta #3
Um serviço compartilhado é a melhor abordagem
export class SharedService {
globalVar:string;
}
Mas você precisa ter muito cuidado ao registrá-lo para poder compartilhar uma única instância por toda a sua aplicação. Você precisa defini-lo ao registrar sua aplicação:
bootstrap(AppComponent, [SharedService]);
Mas não para defini-lo novamente dentro dos atributos providers de seus componentes:
@Component({
(...)
providers: [ SharedService ], // No
(...)
})
Caso contrário, uma nova instância do seu serviço será criada para o componente e seus subcomponentes.
Você pode dar uma olhada nesta pergunta sobre como injeção de dependência e injetores hierárquicos funcionam no Angular 2:
- Qual é a melhor maneira de injetar um serviço em outro no Angular 2 (Beta)?
Você deve notar que também pode definir propriedades Observable no serviço para notificar partes de sua aplicação quando suas propriedades globais mudarem:
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);
}
}
Veja esta pergunta para mais detalhes:
- Delegação: EventEmitter ou Observable no Angular
Resposta #4
Veja, por exemplo, Angular 2 - Implementação de serviços compartilhados
@Injectable()
export class MyGlobals {
readonly myConfigValue:string = 'abc';
}
@NgModule({
providers: [MyGlobals],
...
})
class MyComponent {
constructor(private myGlobals:MyGlobals) {
console.log(myGlobals.myConfigValue);
}
}
ou fornecer valores individuais
@NgModule({
providers: [{provide: 'myConfigValue', useValue: 'abc'}],
...
})
class MyComponent {
constructor(@Inject('myConfigValue') private myConfigValue:string) {
console.log(myConfigValue);
}
}
Resposta #5
Crie a classe Globals em app/globals.ts:
import { Injectable } from '@angular/core';
Injectable()
export class Globals{
VAR1 = 'value1';
VAR2 = 'value2';
}
No seu 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: Você pode adicionar o provedor de serviço Globals diretamente ao módulo em vez do componente, e não precisará adicioná-lo como provedor em cada componente desse módulo.
@NgModule({
imports: [...],
declarations: [...],
providers: [ Globals ],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
Resposta #6
Na minha humilde opinião, para Angular2 (v2.2.3), a melhor maneira é adicionar serviços que contenham a variável global e injetá-los nos componentes sem a tag providers dentro da anotação @Component. Dessa forma, você consegue compartilhar informações entre os componentes.
Um serviço de exemplo que possui uma variável global:
import { Injectable } from '@angular/core'
@Injectable()
export class SomeSharedService {
public globalVar = '';
}
Um componente de exemplo que atualiza o valor da sua variável global:
import { SomeSharedService } from '../services/index';
@Component({
templateUrl: '...'
})
export class UpdatingComponent {
constructor(private someSharedService: SomeSharedService) { }
updateValue() {
this.someSharedService.globalVar = 'updated value';
}
}
Um componente de exemplo que lê o valor da sua variável global:
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
}
}
Observe que
providers: [ SomeSharedService ]não deve ser adicionado à sua anotação@Component. Ao não adicionar esta linha, a injeção sempre fornecerá a mesma instância deSomeSharedService. Se você adicionar a linha, uma nova instância será injetada.
Resposta #7
Eu não sei a melhor maneira, mas a maneira mais fácil se você quiser definir uma variável global dentro de um componente é usar a variável window para escrever assim:
window.GlobalVariable = "what ever!"você não precisa passá-lo para o bootstrap ou importá-lo em outros lugares, e ele é acessível globalmente a todo JS (não apenas aos componentes do Angular 2).
