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 
    } 

Извините за тратить время каждого. Еще раз спасибо.

+0

Как выглядят ваши определения компонентов, в частности их параметры обнаружения изменений и поставщиков? – Douglas

+0

В качестве первого шага я предлагаю вставить конструктор 'console.log (...)' в конструктор службы, чтобы определить, действительно ли вы создаете несколько экземпляров службы. –

+0

@MarkRajcok Хорошо, я сделал это, кажется, только один экземпляр создается. Но независимо от того, только компонент, выполняющий обновление, видит изменения. Я помещу больше кода в свой пост. –

ответ

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 
    } 
0

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

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

enter image description here

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

+0

«Так что только компонент, который изменяется, и его подпункт компоненты переизлучаются ». Это неправда. Когда выполняется определение углового изменения (которое происходит после любого асинхронного события), по умолчанию все компоненты проверяются на изменение. Все изменения, которые были изменены, повторно отображаются. Только если вы укажете 'OnPush' на компоненте, его можно пропустить при грязной проверке обнаружения изменений. –

1

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

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

@Component({ 
    providers: [LocalStorage] 
}) 

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

Смежные вопросы