web-dev-qa-db-fra.com

Comment puis-je surveiller les modifications apportées à localStorage dans Angular2?

J'essayais de comprendre comment obtenir un menu qui apparaît et disparaît après avoir été connecté dans un message précédent. Mais je pense qu'une question meilleure et peut-être plus facile serait, comment puis-je surveiller les modifications apportées au stockage local?

J'utilise des jetons Web Json dans le stockage local pour mon authentification. J'aimerais beaucoup voir un changement dans localStorage, puis mettre à jour mon point de vue sur les nouvelles informations.

Je mets mon stockage local avec cette

localStorage.setItem('jwt', my_token);

Ce que je voudrais faire, c'est vérifier si j'ai un jeton, si rien ne se passe, mais quand il y a un changement, déclenche un événement. J'aimerais particulièrement si je ne pouvais surveiller qu'un événement nommé tel que localStorage.getItem ('jwt').

Merci!

MODIFIER:

Gunter m'a dirigé dans la bonne direction, mais juste au cas où quelqu'un serait encore assez dérouté par cela, voici un plunker vous montrant comment faire. http://plnkr.co/edit/TiUasGdutCsll1nI6USC?p=preview

19
Morgan G

L'essentiel est d'utiliser window.addEventListener("storage",. Tandis que la bibliothèque le fait probablement de la "bonne" manière pour angular, voici une version "légère" que j'ai composée, en utilisant .bind (this) au lieu de fouiller dans les éléments internes de angular.

import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/share'

@Injectable()
export class StorageService implements OnDestroy {
  private onSubject = new Subject<{ key: string, value: any }>();
  public changes = this.onSubject.asObservable().share();

  constructor() {
    this.start();
  }

  ngOnDestroy() {
    this.stop();
  }

  public getStorage() {
    let s = [];
    for (let i = 0; i < localStorage.length; i++) {
      s.Push({
        key: localStorage.key(i),
        value: JSON.parse(localStorage.getItem(localStorage.key(i)))
      });
    }
    return s;
  }

  public store(key: string, data: any): void {
    localStorage.setItem(key, JSON.stringify(data));
    // the local application doesn't seem to catch changes to localStorage...
    this.onSubject.next({ key: key, value: data})
  }

  public clear(key) {
    localStorage.removeItem(key);
    // the local application doesn't seem to catch changes to localStorage...
    this.onSubject.next({ key: key, value: null });
  }


  private start(): void {
    window.addEventListener("storage", this.storageEventListener.bind(this));
  }

  private storageEventListener(event: StorageEvent) {
    if (event.storageArea == localStorage) {
      let v;
      try { v = JSON.parse(event.newValue); }
      catch (e) { v = event.newValue; }
      this.onSubject.next({ key: event.key, value: v });
    }
  }

  private stop(): void {
    window.removeEventListener("storage", this.storageEventListener.bind(this));
    this.onSubject.complete();
  }
}

 LocalStorageTwoTabs

20
Stephen

Utilisez un service et accédez uniquement à LocalStorage via ce service, où que vous soyez.
Le service peut alors fournir des observables qui émettent des événements sur les modifications et vous pouvez vous abonner à ces observables pour être averti.

18
Günter Zöchbauer

Je sais que ce post est un peu vieux, mais il y a des bibliothèques qui peuvent le faire pour vous. Par exemple, h5webstorage vous permettra de traiter localStorage et sessionStorage comme des objets ordinaires et la synchronisation sera gérée automatiquement. Même les modifications apportées directement au stockage seront redistribuées dans votre application.

1
SirDarquan