特定于当前登录用户的数据对象


  • 目标是用户可以在objuserA中保存多达7个字段值,注销,重新登录,保存的瓦尔在那里,可检索。特定于每个用户。
  • 我正在尝试创建一个对象,userA并更新它,作为 用户保存每个字段值(BaseMap: basemapSaved(,保存 本地存储中的更新状态,然后使用 本地存储。因此,当用户注销,然后重新登录时,他们的 保存的数据仍然存在,特定于其用户名。

以下是我最近的尝试(完整的js(:有什么指示吗?我做错了吗?

下面更新了赏金的尝试


我只是试图保存一个数据对象和其中的字段(即userA.BaseMap.basemapSaved;( 与本地存储,单击。

我稍后想解析本地存储中保存的对象,获取该字段,并使用保存和收集的值更新我的 API 对象,object.data.field(userA.BaseMap.basemapSaved;(。我可以在语法上很容易地做到这一点,但这个想法是保存每个用户的状态,以便他们可以注销,然后重新登录并保存他们的选择。

// Here I am trying to initialize the variables
var currentUser;
var basemapSaved;
var userA[key] = {};
// This function I am getting the logged in username, I want to set this as the object key in userA i.e. userA[key]
function checkUser()  { 
var node = document.querySelectorAll("span.username")[0];
currentUser = node.textContent;
var key = currentUser;
console.log("current user is:" + key);
}
// This is just a handler to wait to my basemap gallery loads before trying to save
var basemapMod = document.getElementsByClassName("basemap")[0]; 
basemapMod.addEventListener('click', ()=>{ 
setTimeout(
function() {
BaseMapSaver();
}, 2000);
});
function BaseMapSaver() {
savebtnBM.addEventListener('click', ()=>{ 
checkUser();
// This is where I get the data from my API to save, gathers fine
basemapSaved = app.widget.Manager.Gallery.activeBasemap.Item.id;
// Below I am trying to set it, at first without the object key but would like to use the key
var saveMap = localStorage.setItem('userA', JSON.stringify(userA));
console.log(userA);
});
}
// Home button
var defaultViewHbtn = document.getElementById("home");
defaultViewHbtn.addEventListener('click', ()=>{
checkUser();
// Here I try to parse the value from local storage object
const userAParseValue = JSON.parse(localStorage.getItem('userA'));
// Errors with Uncaught TypeError: Cannot read property 'BaseMap' of undefined
userBaseMap = userAParseValue.userA.BaseMap.basemapSaved;
console.log(userBaseMap);
app.widget.Manager.Gallery.activeBasemap.Item.id = {
portalItem: {
id: userA.BaseMap.basemapSaved // this is where I want to load saved value from local storage object
}
};
});

它应该工作检查addEventListener函数:-

Hbtn.addEventListener('click', ()=>{
checkUser();
const userAParseValue = JSON.parse(localStorage.getItem('userA'));
userBaseMap = userAParseValue.userA.BaseMap.basemapSaved; 
console.log(userBaseMap);
myApp.widgets.bigData.Gallery.map = {
Item: {
id: userA.BaseMap.basemapSaved
}
};
});

您可以使用localStorage和您尝试工作的方法,但最终localStorage每个用户都有一个单独的对象。如果没问题,则在加载后使用localStorage来检查用户是否已登录,然后加载用户的数据。然后在值更改时将数据更新到localStorage。您可以查看内联评论以了解详细信息:

如果有用户登录,则为 HTML:

<h3>User <span class="username"><?php echo $user; ?></span> is logged in</h3>
<form method="post">
<input type="hidden" name="action" value="logout"/>
<button type="submit">Logout</button>
</form>
<hr/>
<div>
<h2>User counter: <span id="counter"></span></h2>
<div>
<button id="inc-counter">Increase</button> 
<button id="dec-counter">Decrease</button>
</div>
</div>

Javascript 来处理localStorage

// Get user stored on page HTML
const user = document.querySelector("span.username");
// Something to update/alter using user data and/or user input
const counter = document.querySelector("#counter");
const incCounter = document.querySelector("#inc-counter");
const decCounter = document.querySelector("#dec-counter");
if(user) { // If there is a user logged in
// Get the username
const username = user.textContent;
// Get the localStorage the belongs to that user (using username for key)
let storageUser = JSON.parse(localStorage.getItem(username) || 'null');
// Use default user object if the user has no previous settings stored
let currentUser = storageUser || {
BaseMap: {
counter: 0
}
};
// Display the user data
function displayCounter() {
const BaseMap = 'BaseMap' in currentUser ? currentUser.BaseMap : {};
let userCounter = 'counter' in BaseMap ? BaseMap.counter : 0;
counter.textContent = userCounter;
}
// Alter the user data and save it to localStorage user settings object
function alterCounter(addToCounter) {
// Check if BaseMap object exists or default
const BaseMap = 'BaseMap' in currentUser ? currentUser.BaseMap : {};
// Check if data exists or default
let userCounter = 'counter' in BaseMap ? BaseMap.counter : 0;
// Alter user data according to user input
userCounter += addToCounter;
// Change user settings object
currentUser['BaseMap']['counter'] = userCounter;
// Save user settings object
localStorage.setItem(username, JSON.stringify(currentUser));
// Display altered user data
displayCounter();
}
// Initialize by display retrieved/default data
displayCounter();
// Add event listeners to user inputs
incCounter.addEventListener('click', () => alterCounter(1));
decCounter.addEventListener('click', () => alterCounter(-1));
}

您可以在下面的链接中查看我制作的在线示例:

https://zikro.gr/dbg/so/60010743/(用户userAuserB两者都有密码1234可用于演示(

这将工作并使用每个用户的username检索/保存用户数据到localStorage。请记住,此方法只会保存特定浏览器位置的用户设置。如果您希望在用户从任何地方登录时进行用户设置,那么您应该使用基于服务器会话的传统解决方法,但在用户设置方面它并不那么灵活,因为您必须使用服务器请求更新每个数据/设置每次用户进行更改时,这是可能的,但它需要服务器 + 客户端实现。

服务器端设置存储 + 服务器会话 + 客户端localStorage的组合将是处理这种情况的最佳方法。

这是我的答案

<html>
<body>
	<span class="border username">121</span>
	<div class="border basemap">Base Map</div>
	<div class="border saveBtn">Save</div>
	<div id="home" class="border">Home</div>
	<style>
		.border{
			border: solid gray 1px;
			border-radius: 2px;
			text-align: center;
			background: #eee;
			margin: 5px;
			width: 100px;
		}
	</style>
	<script type="text/javascript">
		// Here I am trying to initialize the variables
		var key = 1;
		var currentUser;
		var basemapSaved;
		var userA = {
			BaseMap: {
				id: 1234
			}
		};
		var app = {
			widget: {
				Manager: {
					Gallery: {
						activeBasemap: {
							Item: {
								id: {
				portalItem: {
										id: 1234 // this is where I want to load saved value from local storage object
									}
								}
							}
						}
					}
				}
			}
		};
		// This function I am getting the logged in username, I want to set this as the object key in userA i.e. userA[key]
		function checkUser()  { 
			var node = document.querySelectorAll("span.username")[0];
			currentUser = node.textContent;
			var key = currentUser;
			console.log("current user is:" + key);
		}
		// This is just a handler to wait to my basemap gallery loads before trying to save
		var basemapMod = document.getElementsByClassName("basemap")[0]; 
		basemapMod.addEventListener('click', ()=>{ 
			console.log("basemapMod click");
			setTimeout(
				function() {
					BaseMapSaver();
				}, 2000);
		});
		function BaseMapSaver() {
			var savebtnBM = document.getElementsByClassName("saveBtn")[0];
			savebtnBM.addEventListener('click', ()=>{ 
				console.log("savebtnBM click");
				checkUser();
				// This is where I get the data from my API to save, gathers fine
				basemapSaved = app.widget.Manager.Gallery.activeBasemap.Item.id.portalItem.id;

/** saving users, instead of userA */
				const userAParseValue = JSON.parse(localStorage.getItem('users'));
				userA.BaseMap.basemapSaved = basemapSaved;
				const finalUsers = {...userAParseValue, userA}
				// Below I am trying to set it, at first without the object key but would like to use the key
				var saveMap = localStorage.setItem('users', JSON.stringify(finalUsers));
				console.log(userA);
			});
		}
		// Home button
		var defaultViewHbtn = document.getElementById("home");
		defaultViewHbtn.addEventListener('click', ()=>{
			console.log("defaultViewHbtn click");
			checkUser();
			// Here I try to parse the value from local storage object
			const userAParseValue = JSON.parse(localStorage.getItem('users'));
			// Errors with Uncaught TypeError: Cannot read property 'BaseMap' of undefined
			userBaseMap = userAParseValue.userA.BaseMap.basemapSaved;
			console.log(userBaseMap);
			app.widget.Manager.Gallery.activeBasemap.Item.id = {
				portalItem: {
						id: userA.BaseMap.basemapSaved // this is where I want to load saved value from local storage object
					}
				};
		});
	</script>
</body>
</html>

我改变了一些不连贯的结构。保存和加载它们会导致差异。我还建议将所有用户存储在单个对象中并从userMap访问数据,因为多个用户可以使用相同的浏览器。

根据您在原始问题中定义的两个要求,这应该按照您的要求进行操作。

目标是用户可以在obj userA中保存多达7个字段值,注销,重新登录,保存的瓦尔在那里,可检索。特定于每个用户。

我正在尝试创建一个对象,即userA并更新它,因为用户保存每个字段值(即底图:basemapSaved(,将更新的状态保存在本地存储中,然后使用本地存储检索保存的状态。因此,当用户注销然后重新登录时,他们保存的数据仍然存在,特定于他们的用户名。

// retrieve user from localstorage. defaults to {}
// This looks to retrieve the user from local storage by username.
// Returns a `userObj` an object with two properties.
// `username` - the name of the user
// `user` - the stored object that was retrieved from local storage.
//          defaults to {} if nothing in user storage
// Not a good strategy btw, a lot of us share the same names :)
function getUser(username) {
let user = localStorage.getItem(username) || {};
try {
user = JSON.parse(user);
} catch (e) {
user = {};
}
return { username, user }
}
// Store user object in localstorage
// Store a user in local storage, keyed by their username
function setUser(username, user) {
localStorage.setItem(username, JSON.stringify(user));
}
// set a key/ value on user object in localstorage
// Don't allow anymore than 7 properties to be stored on the user object
function setUserProperty(userObj, key, value) {
let { username, user } = userObj;
if (Object.keys(user).length > 7) {
throw new Error('user properties exceeds 7')
}
user[key] = value;
setUser(username, user);
}

// modified to return a user from local storage or {}
function checkUser()  { 
var node = document.querySelectorAll("span.username")[0];
const currentUser = node.textContent;
return getUser(currentUser);
}
// This is just a handler to wait to my basemap gallery loads before trying to save
var basemapMod = document.getElementsByClassName("basemap")[0]; 
basemapMod.addEventListener('click', () => { 
setTimeout(
function() {
BaseMapSaver();
}, 2000);
});
// Fyi Capitals indicate constructors - not functions!
function BaseMapSaver() {
savebtnBM.addEventListener('click', () => { 
const userObj = checkUser(); // get the user from localstorage
const basemapSaved = app.widget.Manager.Gallery.activeBasemap.Item.id;
setUserProperty(userObj, 'basemap', basemapSaved) // store the basemap on the user object in local storage with the key 'basemap'
console.log(JSON.stringify(userObj));
});
}

var defaultViewHbtn = document.getElementById("home");
defaultViewHbtn.addEventListener('click', () => {
// get user from localstorage
const { user } = checkUser();
const userBaseMap = user.basemap
// if we have a store basemap
if (userBaseMap) {
app.widget.Manager.Gallery.activeBasemap.Item.id = {
portalItem: {
id: userBaseMap // load it
}
};
}
});

根据您的用例,有很多方法可以处理此问题。您特别提到了 LocalStorage,因此每个人都建议这样做,但只要您正确处理它们的到期时间,cookie 就会适合您的账单。

  1. 本地存储

创建要为该用户存储的字段的对象

let obj = {'keyname' : value, 'keyname' : value}; 
//store it - mapping it with user
localStorage.setItem('userID', JSON.stringify(obj));
//retrieve and use on login success
let ret_obj= localStorage.getItem('userID');
  1. >饼干

您可以设置任意过期时间,然后再次选择仅选择一个变量或将其存储为 JSON 本身。

document.cookie = "userName=Robert; expires=Fri, 31 Dec 9999 23:59:59 GMT"; 

*Cookie 将保存有限数量的数据,就像在不是巨大的数据中一样(我认为这不是这里的用例,因为我检查了您的 jsfiddle 示例,您基本上是在尝试存储一些数据(

如果您想将 JSON 数据存储在 cookie 中,请查看此 点击这里

*我为什么建议饼干?许多企业已经在做类似的事情,例如,甚至在您访问网站时退出登录 他们将显示您的姓名并要求您登录,这只是一个 个性化添加。

最新更新