Angular 4/5/6 Global Variables


116

Naprawdę zmagam się z tworzeniem zmiennych globalnych w mojej aplikacji Angular 2.

Już googlowałem i czytałem wiele postów na StackOverflow na ten temat przez ostatnie 3 godziny, jednak wygląda na to, że po prostu nie mogę sprawić, by działało. Naprawdę mam nadzieję, że możesz mi pomóc i przepraszam za zadanie tego pytania.

Mam więc plik o nazwie globals.ts , który wygląda następująco:

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


@Injectable()
export class Globals {

  var role = 'test';

}

I chcę użyć zmiennej roli w moim widoku HTML mojego komponentu w następujący sposób:

{{ role }} 

Dodałem już plik globals.ts do mojego app.module.ts w następujący sposób:

providers: [
  Globals
],

Bez względu na to, co zrobiłem z tym plikiem, po prostu nie zadziałało. Nie chcę ręcznie importować pliku globals.ts w każdym komponencie, dlatego chcę skorzystać z funkcji dostawców.

Naprawdę mam nadzieję, że możesz mi pomóc i jeszcze raz przepraszam.

Z poważaniem,

AE


4
export class Globals { var role = 'test'; }<- co to jest?
zerkmy

To ma być moja klasa Globals, w której chcę przechowywać moje zmienne globalne. Na przykład zmienna „rola”, która w tej chwili powinna zawierać ciąg znaków „test”, aby sprawdzić, czy zmienne globalne działają.
AE

Nie jest to jednak poprawny maszynopis.
zerkmy

Czy powinienem usunąć „var”?
AE

a co z używaniem localStorage?
suhailvs

Odpowiedzi:


180

Możesz uzyskać dostęp do Globalsjednostki z dowolnego punktu aplikacji za pośrednictwem iniekcji zależności Angular . Jeśli chcesz wypisać Globals.rolewartość w szablonie jakiegoś komponentu, powinieneś wstrzyknąć Globalsprzez konstruktor komponentu jak każdą usługę:

// hello.component.ts
import { Component } from '@angular/core';
import { Globals } from './globals';

@Component({
  selector: 'hello',
  template: 'The global role is {{globals.role}}',
  providers: [ Globals ] // this depends on situation, see below
})

export class HelloComponent {
  constructor(public globals: Globals) {}
}

Podałem Globalsw HelloComponent, ale zamiast tego może być dostarczony w jakimś HelloComponent'skomponencie nadrzędnym lub nawet w AppModule. Nie będzie to miało znaczenia, dopóki nie będziesz Globalsmieć tylko statycznych danych, których nie można zmienić (powiedzmy, tylko stałe). Ale jeśli nie jest prawdą i na przykład różne komponenty / usługi mogą chcieć zmienić te dane, to Globalsmusi być singletonem . W takim przypadku należy go podać na najwyższym poziomie hierarchii, w której będzie używany. Powiedzmy, że to jest AppModule:

import { Globals } from './globals'

@NgModule({
  // ... imports, declarations etc
  providers: [
    // ... other global providers
    Globals // so do not provide it into another components/services if you want it to be a singleton
  ]
})

Nie można też używać var w taki sposób, jak powinno

// globals.ts
import { Injectable } from '@angular/core';

@Injectable()
export class Globals {
  role: string = 'test';
}

Aktualizacja

W końcu stworzyłem proste demo na stackblitz , w którym pojedynczy Globalsjest dzielony między 3 komponenty, a jeden z nich może zmienić wartość Globals.role.


3
Ale kiedy dostaję go w innym komponencie (coś = globals.role;) otrzymuję „test” .. Nie wartość, którą mu przypisałem.
punkouter

3
@punkouter Zaktualizowałem odpowiedź za pomocą linku do wersji demonstracyjnej Plunkera. Mam nadzieję, że to ci pomoże!
dhilt

3
To trochę stary wątek, ale chcę tylko powiedzieć, że cię kocham. Uratowałem mój dzień!
Nie Selam

2
@AtulStha Właśnie przeniosłem demo z Plunkera do Stackblitz, dzięki za problem.
dhilt

1
@GauravSachdeva Możesz opublikować swój problem jako osobne pytanie na SO, uważam, że byłaby to najlepsza opcja. Dodaj link do niego w komentarzach, jeśli chcesz, żebym go zobaczył.
dhilt

22

Używam do tego środowiska. Działa automatycznie i nie musisz tworzyć nowej usługi iniekcyjnej, a najbardziej przydatne dla mnie, nie musisz importować za pomocą konstruktora.

1) Utwórz zmienną środowiskową w swoim environment.ts

export const environment = {
    ...
    // runtime variables
    isContentLoading: false,
    isDeployNeeded: false
}

2) Zaimportuj environment.ts do pliku * .ts i utwórz zmienną publiczną (np. „Env”), aby móc ją wykorzystać w szablonie html

import { environment } from 'environments/environment';

@Component(...)
export class TestComponent {
    ...
    env = environment;
}

3) Użyj go w szablonie ...

<app-spinner *ngIf='env.isContentLoading'></app-spinner>

w * .ts ...

env.isContentLoading = false 

(lub po prostu environment.isContentLoading na wypadek, gdybyś nie był potrzebny do szablonu)


Możesz stworzyć swój własny zestaw zmiennych globalnych w environment.ts w następujący sposób:

export const globals = {
    isContentLoading: false,
    isDeployNeeded: false
}

i importuj bezpośrednio te zmienne (y)


1
A co z tworzeniem wersji produkcyjnej? Masz wszystko w dwóch miejscach?
Mulperi

2
To najlepszy sposób. @Mulperi Nie jest konieczne do tworzenia globali w environment.ts. Po prostu utwórz plik globals.ts w katalogu aplikacji z powyższymi eksportami i zaimportuj ten plik tam, gdzie chcesz użyć tych globali.
PrasadW

1
Zgadzam się. Niedawno zmodyfikowałem to rozwiązanie dokładnie tak, jak wskazał @PrasadW.
Martin Slavkovsky

Nowe wersje Angular domyślnie używają dokładnie tego podejścia. Istnieje environments/environment.tsi, environments/environment.prod.tsktóre są zastępowane automatycznie.
dywanik

0

Niezbyt zalecane, ale żadna z pozostałych odpowiedzi nie jest tak naprawdę zmiennymi globalnymi. W przypadku prawdziwie globalnej zmiennej możesz to zrobić.

Index.html

<body>
  <app-root></app-root>
  <script>
    myTest = 1;
  </script>
</body>

Komponent lub cokolwiek innego w Angular

..w prawym górnym rogu po zaimportowaniu:

declare const myTest: any;

...później:

console.warn(myTest); // outputs '1'

-2

Możesz użyć obiektu Window i uzyskać do niego dostęp wszędzie. przykład window.defaultTitle = "mój tytuł"; wtedy możesz uzyskać dostęp do window.defaultTitle bez importowania czegokolwiek.


Tego chce uniknąć.
Scandinave
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.