0

在我的 Angular2 应用程序中,我正在引导一个LocalStorage我希望在我的组件之间共享的身份验证服务:

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    LocalStorage
]);

LocalStorage定义如下:

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);
    }
}

但是,问题是,当我跨组件共享和更新它时,只有更新它的组件才能识别更改。它被注入到组件中并像这样编辑:

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

        ...
    }

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

为什么似乎跨组件创建了该服务的多个实例?谢谢。

编辑组件模板绑定的示例是:

零件:

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);
    }
}

模板:

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

最终编辑

好吧,这很尴尬,在实际编辑服务中的用户名之后,它现在可以工作了:

    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
    }

很抱歉浪费了大家的时间。再次感谢。

4

3 回答 3

1

这是因为您在代码中的某处将 LocalStorage 指定为提供程序。

检查您的任何组件是否包含:

@Component({
    providers: [LocalStorage]
}) 

这给出了一个 Injector 指令,为该组件和所有子组件创建一个新实例,如果子组件本身没有提供的 LocalStorage。

于 2016-03-08T14:40:40.643 回答
0

我忘了在服务本身中实际修改用户名:

    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
    }
于 2016-03-08T14:04:07.293 回答
0

但是,问题是,当我跨组件共享和更新它时,只有更新它的组件才能识别更改

这是因为 Angular 2 组件模型是树:

在此处输入图像描述

所以只有发生变化的组件及其子组件会被重新渲染。对于包含跨组件使用的状态的单例之类的东西,您需要以下内容reduxhttps ://medium.com/google-developer-experts/angular-2-introduction-to-redux-1cf18af27e6e#.yk11zfcwz

于 2016-03-07T23:03:45.313 回答