web-dev-qa-db-fra.com

Fournisseur de service global Angular2

/app
        - app.component.ts 
        - app.component.html (hide/show: menu bar)
        - app.global.service.ts (Public varible LoginSuccess:boolean)
        - main.ts
        /student
            - student.ts
            - student.service.ts
            - student.component.ts
            - student.component.html
        /security
            - login.component.ts (LoginSuccess = true)
            - login.component.html

Dans mon application de Angular2, j'ai un besoin simple pour lequel je souhaite afficher la barre de menus masquée en fonction du succès de la connexion. Pour cela, j'ai créé un service qui ne contient qu'une variable booléenne LoginSuccess, que je définirais sur le composant de connexion et que j'utiliserais sur app.component.html pour la balise [hidden]=LoginSuccess nav.

Le problème auquel je suis confronté est que, même après l'injection de app.global.service.ts dans constructor de app.component.ts & login.component.ts, la valeur ne persiste pas et chaque constructeur crée un nouvel objet de app.global.service.ts

Question: Comment puis-je obtenir la persistance d’une valeur unique dans l’application via le service? Quelque part dans la documentation Angular2, j'ai lu que le service Injectable est singleton.

14
Avi Kenjale

Vous devez fournir GlobalService au démarrage, et non pour chaque composant:

bootstrap(AppComponent, [GlobalService])

@Component({
  providers: [], // yes
  // providers: [GlobalService], // NO.
})
class AppComponent {
  constructor(private gs: GlobalService) {
    // gs is instance of GlobalService created at bootstrap
  }
}

De cette façon, GlobalService sera un singleton.

Pour une approche plus avancée, voir cette réponse .

28
Sasxa

Vous devriez avoir un app.component.ts et au lieu de booster à l'intérieur de app.module.ts, vous injectez le service dans app.component.ts.

...
import { MusicService } from './Services/music-service';

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html',
    providers: [MusicService],
    ...
})
export class AppComponent {

constructor(private MS: MusicService) {

}
...

Ceci est basé sur la version actuelle de Angular2. Donc, dans index.html, vous devriez avoir <app-root>AppComponent est chargé.

Maintenant, pour l'utiliser dans n'importe quel autre composant, importez le:

import { MusicService } from './Services/music-service';

et l'initialiser:

constructor(private MS: MusicService) {

}

Résumé:

  1. Importer dans app.component.ts
  2. Insérer dans app.component.ts en tant que provider
  3. Initialiser dans le constructeur
  4. Répétez l’étape 2,3 pour tous les autres utilisateurs désirant l’utiliser dans

Référence: Injection de dépendance angulaire

7
theblindprophet

À partir de la version finale (2.0.0 angulaire):

Importez le service et insérez-le dans le tableau providers en procédant comme suit: 

import { GlobalService } from './app.global.service';

//further down:
@NgModule({
  bootstrap: [ App ],
  declarations: [
    // Your components should go here 
  ],
  imports: [ 
    // Your module imports should go here
  ],
  providers: [ 
    ENV_PROVIDERS // By Angular
    // Your providers should go here, i.e.
    GlobalService
  ]
});
4
mareks

En tant que Saxsa, l’essentiel est de définir votre prestataire de services au sein de l’injecteur d’application et non à chaque niveau de composant. Veillez à ne pas définir le fournisseur de services deux fois ... Sinon, vous aurez toujours des instances de service distinctes.

De cette façon, vous pourrez partager la même instance du service.

Ce problème se produit en raison d'injecteurs hiérarchiques de Angular2. Pour plus de détails, vous pouvez jeter un oeil à cette question:

4
Thierry Templier

J'ajouterai simplement que, parce que j'étais bloqué à ce stade, bien que j'aie utilisé un Singelton, vous devez également utiliser le stratag

Vous ne pouvez pas utiliser href = "../ my-route"

parce que cela lance toute la nouvelle application:

à la place, vous devez utiliser: routerLink = "../ my-route"

0
Steffi

À partir de Angular 6.0 , le moyen préféré pour créer un service singleton est de spécifier sur le service qu'il doit être fourni à la racine de l'application. Pour ce faire, définissez providedIn sur root sur le décorateur @Injectable du service:

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

@Injectable({
  providedIn: 'root',
})
export class UserService {
}
0
Ajmal sha