129 votes

Variables globales d'Angular 4/5/6

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

J'ai donc un 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 la variable dans la vue HTML de mon composant comme ceci :

{{ role }} 

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

providers: [
  Globals
],

Peu importe ce que j'ai fait sur ce fichier, ça n'a pas marché. Je ne veux pas avoir à importer manuellement le fichier globals.ts dans chaque composant, c'est pourquoi je veux utiliser la fonctionnalité des fournisseurs.

4 votes

export class Globals { var role = 'test'; } <- c'est quoi ça ?

0 votes

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 contenir la chaîne "test", juste pour tester si les variables globales fonctionnent.

0 votes

Ce n'est pas une écriture valide.

192voto

dhilt Points 7074

Vous pouvez accéder à Globals à partir de n'importe quel point de votre application via Injection de dépendances Angular . Si vous voulez produire Globals.role dans le modèle d'un composant, vous devez injecter la valeur Globals par le biais du 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 Globals dans le HelloComponent mais au lieu de cela, elle pourrait être fournie dans une HelloComponent's parent ou même dans AppModule . Cela n'aura pas d'importance jusqu'à ce que votre Globals n'a que des données statiques qui ne peuvent pas être modifiées (disons, uniquement des constantes). Mais si ce n'est pas le cas et que, par exemple, différents composants/services peuvent vouloir modifier ces données, alors la fonction Globals doit ê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 de la façon dont tu l'as fait, ça devrait être

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

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

Mise à jour

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

3 votes

Mais quand je l'obtiens dans un autre composant (quelque chose = globals.role ;) j'obtiens 'test' Pas la valeur que je lui ai attribuée.

3 votes

@punkouter J'ai mis à jour la réponse avec un lien vers la démo de Plunker. J'espère que cela vous aidera !

5 votes

C'est un peu un vieux sujet mais je veux juste dire que je t'aime. Vous avez sauvé ma journée !

29voto

Martin Slavkovsky Points 149

J'utilise l'environnement pour cela. Il fonctionne automatiquement et vous n'avez pas besoin de créer un 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éer public variable (c'est-à-dire "env") pour pouvoir l'utiliser dans le modèle html

import { environment } from 'environments/environment';

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

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

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

dans *.ts ...

env.isContentLoading = false 

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


Vous pouvez créer votre propre ensemble de globaux dans environment.ts comme suit :

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

et d'importer directement ces variables (y)

2 votes

Qu'en est-il lorsque vous faites une construction de production ? Est-ce que vous avez tout à deux endroits ?

2 votes

C'est le meilleur moyen. @Mulperi Il n'est pas nécessaire de créer des globaux dans environment.ts. Il suffit de créer un globals.ts dans le répertoire app avec les exportations ci-dessus et d'importer ce fichier là où vous voulez utiliser ces globals.

1 votes

Je suis d'accord. J'ai récemment modifié cette solution exactement comme @PrasadW l'a indiqué.

0voto

Azarus Points 940

Alors que toutes les autres réponses mentionnées précédemment sont correctes. La méthode Angular consiste à utiliser des tuyaux, des décorateurs ou des composants.

Si vous souhaitez simplement afficher une chaîne de caractères, utilisez un composant

Composant

<Role></Role>

Décorateur

Si vous voulez faire quelque chose comme ça :

<a href="http://stackoverflow.com/foo/{{userId}}/bar">Link</a>

Vous pouvez implémenter votre propre décorateur

<a [customHref]="[/foo/:userId/bar]">Link</a>

ou si vous utilisez le module routeur intégré avec routerlink, vous pouvez simplement étendre la directive RouterLink et mettre en œuvre vos modifications.

Tuyau

somevariable = "this is my #:userId";

{{someVariable | applyglobals}}

Et ainsi de suite.

-1voto

Helzgate Points 11

Pas vraiment recommandé, mais aucune des autres réponses n'est vraiment une variable globale. Pour une variable vraiment globale, vous pourriez faire ceci.

Index.html

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

Composant ou autre dans Angular

en haut à droite après les importations :

declare const myTest: any;

...plus tard :

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

0 votes

C'est la même chose que d'utiliser l'objet fenêtre.

-2voto

Justice Addico Points 1

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

0 votes

C'est ce qu'il veut éviter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X