服务中保存的数据在页面刷新或更改时丢失

时间:2018-10-26 10:20:03

标签: angular angular-services google-oauth2

我有一个Angular 5应用程序,并且尝试使用Google OAuth登录名获取用户名,然后在服务中将该用户名设置为登录用户。在添加登录名之前,我在服务中手动设置了值,并且没有问题。现在,我正在通过Google登录名设置用户名,看起来每次设置页面刷新时(或调用服务的新实例时)我设置的值都会丢失。

该值从Google登录名正确返回(我在控制台中检查了),因此我知道一切正常。我对Angular服务的印象是,它们在其他模块中是不变的吗?每次我调用该服务时,都会创建一个新的空“ tempuser”变量吗?如果可以的话,有什么办法可以解决,所以我可以在整个应用程序中保留该值,直到用户注销为止。

这是服务本身:

function pValueSorter(a, b) {
    a.children[colNum]
    b.children[colNum]
    ...
}

还有一个简单的示例,将其称为:

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from "@angular/http";

@Injectable()
export class WmApiService {

  //private _baseUrl = "http://wm-api.webdevelopwolf.com/"; // Test server api
  private _baseUrl = "http://localhost:58061/"; // Dev server api 
  tempuser = "";
  tempuseravatar = "";
  tempuserfullname = "";
  tempuseremail = "";
  userloggedin = 0;
  modules: any;

  constructor(private _http: Http) {
    console.log('Wavemaker API Initialized...');
  }

  // On successful API call
  private extractData(res: Response) {
    let body = res.json();
    return body || {};
  }

  // On Error in API Call
  private handleError(error: any): Promise<any> {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  }

  // Basic Get W/ No Body
  getService(url: string): Promise<any> {
    return this._http
        .get(this._baseUrl + url)
        .toPromise()
        .then(this.extractData)
        .catch(this.handleError);
  }

  // Basic Post W/ Body
  postService(url: string, body: any): Promise<any> {
    console.log(body);
    let headers = new Headers({'Content-Type': 'application/json'});
    return this._http
      .post(this._baseUrl + url, body, {headers: headers})
      .toPromise()
      .then(this.extractData)
      .catch(this.handleError);
  }

}

临时用户值设置如下:

import { Component, OnInit } from '@angular/core';
import { WmApiService } from '../../wm-api.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  userSignedToJourney: boolean;

  constructor(private _wmapi: WmApiService) { }

  ngOnInit() {
    this.userRegisteredToJourney();
  }

  // Check if Trailblazer is already on Journey
  userRegisteredToJourney() {
    this._wmapi
    .getService("Journey/TrailblazerRegistered/" + this._wmapi.tempuser)
    .then((result) => {
      if (result == 1) this.userSignedToJourney = true; else this.userSignedToJourney = false;
    })
    .catch(error => console.log(error));
  }

}

3 个答案:

答案 0 :(得分:1)

有些东西在这里看起来乱七八糟。

  1. 依赖注入错误

您要将WM API服务注入到该组件中,然后在其中进行配置。事实并非如此,您应该在服务本身和init上执行此操作。并且,在获取此Google API数据之前,该服务不应处于“就绪”状态。一方面,您的组件不必关心配置服务,而只是要求提供服务并使用它们。其次,如果您在其他地方使用服务,例如当没有登录组件时,谁来配置您的服务?第三,如果您有该服务的多个实例,则可能意味着您做错了-您应该在全局应用程序级别上提供服务,以便它们都使用同一实例,但是即使没有,您仍然需要服务要照顾它的依赖性,而不是服务使用者。

纠正此特定部分的步骤:

  • 从组件中取出gapi.load()等东西并将其放入服务中
  • 尽可能在应用程序级别而不是组件(或惰性模块)级别上提供服务。

    1. 页面重新加载问题

可能其中一些是持久性的-您说在页面重新加载时丢失了一些东西。这只是合乎逻辑的-每次重新加载页面时,内存中的内容就会消失,并且您有了一个全新的应用程序。也许您想存储诸如JWT令牌之类的东西并将内容访问到sessionStoragelocalStorage中。如果有这样的东西需要在整个页面重新加载过程中保持不变,则还应该在您的应用程序中构建并提供存储服务,该存储服务向WM API服务(及其他)提供序列化/反序列化服务。再次,此存储注入了WM Api服务,因此它可以在启动时自行配置(在其构造函数中)。

  1. Http错误

HttpHeadersResponse,基本上整个@angular/http在Angular 4.3中已弃用-您应该使用HttpClient和{{1}的朋友}。更改应该非常简单,这是值得的。 另外,请尝试在Http客户端上的@angular/common/http之间和自己之间进行观察。它将使应用程序中的其他事物(也包括可观察对象)的工作变得更容易,并且更改也相对较小-成功或失败后Http(Client)可观察对象无论如何都会完成,因此您的逻辑应该仍然相同(只需使用{{ 1}},而不是.toPromise()

  1. 文档

我看到您也在使用subscribe(successHandler, errHandler)(可能还有其他东西)。您最好不要直接使用浏览器全局变量,而是注入Angular提供的代理。从长远来看,您会感谢自己所做的。

答案 1 :(得分:1)

是的,您可以在Angular中拥有service的多个实例,但每次调用时都不能。服务在相同级别个模块中具有相同实例。因此,要具有服务的单个实例,请在app.module.ts中提供它。此外,存储在服务中的任何数据在刷新时都会丢失。您可以将localStoragesessionStorage用于相同的目的。

答案 2 :(得分:0)

我也遇到了刷新页面时数据丢失的相同问题。您需要在 app.module.ts 的 providers 部分下添加服务详细信息。此外,利用 localStorage 来存储数据。当页面刷新时,从localStorage中检索数据。

注意:- 将数据以加密格式存储在 localStorage 中。有一个 javascript 库 crypto-js 可用于加密和解密。