我有一个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));
}
}
答案 0 :(得分:1)
有些东西在这里看起来乱七八糟。
您要将WM API服务注入到该组件中,然后在其中进行配置。事实并非如此,您应该在服务本身和init上执行此操作。并且,在获取此Google API数据之前,该服务不应处于“就绪”状态。一方面,您的组件不必关心配置服务,而只是要求提供服务并使用它们。其次,如果您在其他地方使用服务,例如当没有登录组件时,谁来配置您的服务?第三,如果您有该服务的多个实例,则可能意味着您做错了-您应该在全局应用程序级别上提供服务,以便它们都使用同一实例,但是即使没有,您仍然需要服务要照顾它的依赖性,而不是服务使用者。
纠正此特定部分的步骤:
尽可能在应用程序级别而不是组件(或惰性模块)级别上提供服务。
可能其中一些是持久性的-您说在页面重新加载时丢失了一些东西。这只是合乎逻辑的-每次重新加载页面时,内存中的内容就会消失,并且您有了一个全新的应用程序。也许您想存储诸如JWT令牌之类的东西并将内容访问到sessionStorage
或localStorage
中。如果有这样的东西需要在整个页面重新加载过程中保持不变,则还应该在您的应用程序中构建并提供存储服务,该存储服务向WM API服务(及其他)提供序列化/反序列化服务。再次,此存储注入了WM Api服务,因此它可以在启动时自行配置(在其构造函数中)。
Http
,Headers
,Response
,基本上整个@angular/http
在Angular 4.3中已弃用-您应该使用HttpClient
和{{1}的朋友}。更改应该非常简单,这是值得的。
另外,请尝试在Http客户端上的@angular/common/http
之间和自己之间进行观察。它将使应用程序中的其他事物(也包括可观察对象)的工作变得更容易,并且更改也相对较小-成功或失败后Http(Client)可观察对象无论如何都会完成,因此您的逻辑应该仍然相同(只需使用{{ 1}},而不是.toPromise()
。
我看到您也在使用subscribe(successHandler, errHandler)
(可能还有其他东西)。您最好不要直接使用浏览器全局变量,而是注入Angular提供的代理。从长远来看,您会感谢自己所做的。
答案 1 :(得分:1)
是的,您可以在Angular中拥有service
的多个实例,但每次调用时都不能。服务在相同级别个模块中具有相同实例。因此,要具有服务的单个实例,请在app.module.ts中提供它。此外,存储在服务中的任何数据在刷新时都会丢失。您可以将localStorage
或sessionStorage
用于相同的目的。
答案 2 :(得分:0)
我也遇到了刷新页面时数据丢失的相同问题。您需要在 app.module.ts 的 providers 部分下添加服务详细信息。此外,利用 localStorage 来存储数据。当页面刷新时,从localStorage中检索数据。
注意:- 将数据以加密格式存储在 localStorage 中。有一个 javascript 库 crypto-js 可用于加密和解密。