Почему моя общая служба не обновляется во всех моих компонентах?

В моем приложении 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
    }

Извините за трату времени всех. Еще раз спасибо.

3 ответа

Решение

Я забыл изменить имя пользователя в самом сервисе:

    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
    }

Это потому, что вы назначили LocalStorage в качестве поставщика где-то в вашем коде.

Проверьте, содержит ли какой-либо из ваших компонентов:

@Component({
    providers: [LocalStorage]
}) 

Это дает инструкцию Injector для создания нового экземпляра для этого компонента и всех дочерних элементов, если дочерний элемент снова не имеет предоставленного LocalStorage.

Однако проблема заключается в том, что когда я делю и обновляю его по компонентам, только компонент, который обновляет его, распознает изменения.

Это из-за того, что угловая 2-х компонентная модель дерева:

введите описание изображения здесь

Таким образом, только компонент, который изменяется, и его подкомпоненты перерисовываются. Для таких вещей, как синглтоны, содержащие состояния, используемые в компонентах, вам нужно что-то вроде redux: https://medium.com/google-developer-experts/angular-2-introduction-to-redux-1cf18af27e6e

Другие вопросы по тегам