Dans mon application Angular2, je démarre un service d'authentification LocalStorage que je souhaite partager entre mes composants:

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    LocalStorage
]);

LocalStorage est défini comme suit:

import {JwtHelper} from 'angular2-jwt/angular2-jwt';
import { Injectable } from 'angular2/core';

@Injectable()
export class LocalStorage {

    key:string = 'jwt';
    jwtHelper:JwtHelper = new JwtHelper();
    username:string;

    constructor() {

        let token = localStorage.getItem(this.key);

        if (token == null) return;

        if (this.jwtHelper.isTokenExpired(token)) {
            localStorage.removeItem(this.key);
        } else {
            this.username = this.jwtHelper.decodeToken(token).username;
        }
    }

    login(jwt:string) {
        localStorage.setItem(this.key, jwt);
    }

    logout() {
        localStorage.removeItem(this.key);
    }

    isLoggedIn():boolean {
        return this.username != null;
    }

    getUsername():string {
        return this.username;
    }

    getToken():string {
        return localStorage.getItem(this.key);
    }
}

Le problème est, cependant, lorsque je le partage et le mets à jour entre les composants, seul le composant qui le met à jour reconnaît les modifications. Il est injecté dans les composants et édité comme ceci:

    constructor(private router:Router, private localStorage:LocalStorage) {

        ...
    }

    logout(event) {
        event.preventDefault();
        this.localStorage.logout();
        this.router.navigateByUrl(RoutingPaths.home.path);
    }

Pourquoi semble-t-il que plusieurs instances de ce service sont en cours de création entre les composants? Merci.

Modifier Un exemple de liaison de modèle de composant est:

Composante:

import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {RoutingPaths} from './routing-paths';
import {LoggedInOutlet} from './logged-in-outlet';
import {LocalStorage} from './local-storage'

@Component({
    selector: 'my-app',
    templateUrl: 'app/app.template.html',
    directives: [LoggedInOutlet, ROUTER_DIRECTIVES]
})
export class AppComponent {

    registerName:string;

    constructor(private router:Router, private localStorage:LocalStorage) {
        this.registerName = RoutingPaths.register.name;
    }

    logout(event) {
        event.preventDefault();
        this.localStorage.logout();
        this.router.navigateByUrl(RoutingPaths.home.path);
    }
}

Modèle:

<a *ngIf="!localStorage.isLoggedIn()" [routerLink]="[registerName]">Register</a>

Modification finale

Eh bien, c'est embarrassant, après avoir réellement modifié le nom d'utilisateur dans le service, cela fonctionne maintenant:

    login(jwt:string) {
        localStorage.setItem(this.key, jwt);
        this.username = this.jwtHelper.decodeToken(jwt).username;  // here
    }

    logout() {
        localStorage.removeItem(this.key);
        this.username = null; // here
    }

Désolé d'avoir perdu le temps de tout le monde. Merci encore.

0
Sloth Armstrong 8 mars 2016 à 01:56

3 réponses

Meilleure réponse

J'ai oublié de modifier réellement le nom d'utilisateur dans le service lui-même:

    login(jwt:string) {
        localStorage.setItem(this.key, jwt);
        this.username = this.jwtHelper.decodeToken(jwt).username;  // here
    }

    logout() {
        localStorage.removeItem(this.key);
        this.username = null; // here
    }
0
Sloth Armstrong 8 mars 2016 à 14:04

C'est parce que vous avez attribué LocalStorage en tant que fournisseur quelque part dans votre code.

Vérifiez si l'un de vos composants contient:

@Component({
    providers: [LocalStorage]
}) 

Cela donne une instruction Injector pour créer une nouvelle instance pour ce composant et tous les enfants si l'enfant un n'a pas de LocalStorage lui-même fourni.

1
igorzg 8 mars 2016 à 14:40

Le problème est, cependant, lorsque je le partage et le mets à jour entre les composants, seul le composant qui le met à jour reconnaît les modifications

C'est parce que le modèle de composant angulaire 2 est un arbre:

enter image description here

Ainsi, seul le composant qui change et ses sous-composants sont restitués. Pour des trucs comme les singletons contenant l'état utilisé entre les composants, vous avez besoin de quelque chose comme redux: https://medium.com/google-developer-experts/angular-2-introduction-to-redux-1cf18af27e6e#.yk11zfcwz

0
basarat 7 mars 2016 à 23:03