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.
3 réponses
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
}
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.
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:
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
Questions connexes
De nouvelles questions
javascript
Pour des questions concernant la programmation dans ECMAScript (JavaScript / JS) et ses divers dialectes / implémentations (hors ActionScript). Veuillez inclure toutes les balises pertinentes dans votre question; par exemple, [node.js], [jquery], [json], etc.