Variables globales angulaires 4/5/6

116

J'ai vraiment du mal à créer des variables globales dans mon application Angular 2.

J'ai déjà cherché et lu de nombreux articles sur StackOverflow à ce sujet au cours des 3 dernières heures, mais il semble que je ne peux tout simplement pas le faire fonctionner. J'espère vraiment que vous pourrez m'aider et je m'excuse d'avoir posé cette question.

J'ai donc mon fichier appelé globals.ts , qui ressemble à ceci:

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


@Injectable()
export class Globals {

  var role = 'test';

}

Et je veux utiliser le rôle de variable dans ma vue HTML de mon composant comme ceci:

{{ role }} 

J'ai déjà ajouté le fichier globals.ts à mon app.module.ts de la manière suivante:

providers: [
  Globals
],

Peu importe ce que j'ai fait sur ce fichier, cela n'a tout simplement pas fonctionné. Ce que je ne veux pas faire, c'est avoir à importer manuellement le fichier globals.ts dans chaque composant, c'est pourquoi je souhaite utiliser la fonctionnalité des fournisseurs.

J'espère vraiment que vous pourrez m'aider et désolé à nouveau.

Meilleures salutations,

AE

AE
la source
4
export class Globals { var role = 'test'; }<- qu'est-ce que c'est?
zerkms
C'est censé être ma classe Globals dans laquelle je veux stocker mes variables globales. Par exemple, la variable "role", qui pour l'instant devrait avoir une chaîne "test" dedans, juste pour tester si les variables globales fonctionnent.
AE
Ce n'est pas dactylographié valide cependant.
zerkms
Dois-je supprimer le "var"?
AE
qu'en est-il de l'utilisation localStorage?
suhailvs

Réponses:

180

Vous pouvez accéder à l' Globalsentité à partir de n'importe quel point de votre application via l' injection de dépendances angulaires . Si vous souhaitez générer une Globals.rolevaleur dans le modèle d'un composant, vous devez injecter Globalsvia le constructeur du composant comme n'importe quel service:

// 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) {}
}

J'ai fourni Globalsdans le HelloComponent, mais à la place, il pourrait être fourni dans un HelloComponent'scomposant parent ou même dans AppModule. Cela n'aura pas d'importance tant que vous ne disposerez pas de Globalsdonnées statiques qui ne pourraient pas être modifiées (par exemple, des constantes uniquement). Mais si ce n'est pas vrai et que, par exemple, différents composants / services peuvent vouloir modifier ces données, alors le Globalsdoit être un singleton . Dans ce cas, il doit être fourni au niveau le plus élevé de la hiérarchie où il va être utilisé. Disons que c'est 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
  ]
})

De plus, il est impossible d'utiliser var comme vous l'avez fait, cela devrait être

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

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

Mettre à jour

Enfin, j'ai créé une démo simple sur stackblitz , où single Globalsest partagé entre 3 composants et l'un d'eux peut changer la valeur de Globals.role.

dhilt
la source
3
Mais quand je l'obtiens dans un autre composant (quelque chose = globals.role;) j'obtiens "test" .. Pas la valeur que je lui ai assignée.
punkouter
3
@punkouter J'ai mis à jour la réponse avec un lien de démonstration Plunker. J'espère que cela vous aidera!
dhilt
3
C'est un peu un vieux fil mais je veux juste dire que je t'aime. J'ai sauvé ma journée!
Nie Selam
2
@AtulStha Je viens de déplacer la démo de Plunker vers Stackblitz, merci pour le problème.
Dhilt
1
@GauravSachdeva Vous pouvez publier votre problème sous forme de question distincte sur SO, je pense que ce serait la meilleure option. Ajoutez un lien vers celui-ci dans les commentaires si vous voulez que je le voie.
dhilt le
22

J'utilise l'environnement pour cela. Cela fonctionne automatiquement et vous n'avez pas à créer de nouveau service injectable et le plus utile pour moi, vous n'avez pas besoin d'importer via le constructeur.

1) Créez une variable d'environnement dans votre environnement .ts

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

2) Importez environment.ts dans le fichier * .ts et créez une variable publique (c'est-à-dire "env") pour pouvoir l'utiliser dans un modèle html

import { environment } from 'environments/environment';

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

3) Utilisez-le dans le modèle ...

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

dans * .ts ...

env.isContentLoading = false 

(ou simplement environment.isContentLoading au cas où vous n'en auriez pas besoin pour le modèle)


Vous pouvez créer votre propre ensemble de globals dans environment.ts comme ceci:

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

et importez directement ces variables (y)

Martin Slavkovsky
la source
1
Qu'en est-il lorsque vous créez une production? Avez-vous tout à deux endroits?
Mulperi le
2
C'est la meilleure façon. @Mulperi Pas nécessaire pour créer des globals dans environment.ts. Créez simplement un globals.ts dans le répertoire de l'application avec les exportations ci-dessus et importez ce fichier où vous souhaitez utiliser ces globals.
PrasadW
1
Je suis d'accord. J'ai récemment modifié cette solution exactement comme @PrasadW l'a souligné.
Martin Slavkovsky
Les nouvelles versions angulaires utilisent exactement cette approche par défaut maintenant. Il y a un environments/environment.tset environments/environment.prod.tsqui sont remplacés automatiquement.
rugk
0

Pas vraiment recommandé mais aucune des autres réponses n'est vraiment des variables globales. Pour une variable vraiment globale, vous pouvez le faire.

Index.html

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

Composant ou autre chose dans Angular

..en haut à droite après les importations:

declare const myTest: any;

...plus tard:

console.warn(myTest); // outputs '1'
Helzgate
la source
-2

Vous pouvez utiliser l'objet Window et y accéder partout. exemple window.defaultTitle = "mon titre"; alors vous pouvez accéder à window.defaultTitle sans rien importer.

Le juge Addico
la source
C'est ce qu'il veut éviter.
Scandinave le