объект данных, указывающий c текущему зарегистрированному пользователю - PullRequest
0 голосов
/ 31 января 2020
  • Цель состоит в том, чтобы пользователь мог сохранить до 7 значений полей в obj userA, выйти из системы, снова войти в систему и сохранить сохраненные значения, которые можно восстановить. Специфика c каждому пользователю.
  • Я пытаюсь создать объект т.е. userA и обновить его, так как пользователь сохраняет каждое значение поля ( т.е. BaseMap: basemapSaved), сохраняя обновленное состояние в локальном хранилище, затем восстановить сохраненное состояние, используя локальное хранилище. Поэтому, когда пользователь выходит из системы, а затем снова входит в систему, его сохраненные данные все еще находятся там, указав c свое имя пользователя.

Ниже приведена моя самая последняя попытка (полная js): Есть указатели? Я все об этом ошибаюсь?

ОБНОВЛЕНО ПОПЫТКА НИЖЕ С BOUNTY .


Я просто пытаюсь сохранить объект данных и поле внутри него (т. е. 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
            }
          };
    });

Ответы [ 5 ]

1 голос
/ 14 февраля 2020

Исходя из двух требований, которые вы определили в исходном вопросе, это должно делать то, что вы спрашиваете.

Цель состоит в том, чтобы пользователь мог сохранить до 7 значений полей в obj userA, выйти из системы, выйти из системы. в и сохраненные значения там, извлекаемые. Определить c для каждого пользователя.

Я пытаюсь создать объект, т.е. userA, и обновить его, так как пользователь сохраняет каждое значение поля (т.е. BaseMap: basemapSaved), сохраняет обновленное состояние в локальном хранилище, затем восстановить сохраненное состояние, используя локальное хранилище. Таким образом, когда пользователь выходит из системы, а затем снова входит в систему, его сохраненные данные все еще остаются там, указывая c на свое имя пользователя.

// 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
            }
        };
    }
});

1 голос
/ 10 февраля 2020

Вы можете использовать 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/ (пользователи userA, userB оба с паролем 1234 может использоваться для демонстрации)

Это будет работать и извлекать / сохранять пользовательские данные в localStorage, используя username для каждого пользователя. Имейте в виду, что этот метод сохранит пользовательские настройки только для указанного местоположения браузера c. Если вы хотите иметь пользовательские настройки, когда пользователь входит в систему из любого места, то вам следует go использовать традиционный обходной путь, основанный на сеансе сервера, но он не настолько гибок, когда речь идет о пользовательских настройках, потому что вам придется обновить Каждые данные / настройки с использованием запросов к серверу каждый раз, когда пользователь вносит изменения, которые возможны, но это требует реализации сервер + клиент.

Комбинация хранения настроек на стороне сервера + сеанс сервера + клиент localStorage будет лучший подход к этой ситуации.

1 голос
/ 14 февраля 2020

вот мой ответ

<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, поскольку несколько пользователей могут использовать один и тот же браузер.

1 голос
/ 01 февраля 2020

Должно работать, проверьте функцию 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
            }
          };
    });
0 голосов
/ 17 февраля 2020

Есть много способов справиться с этим в зависимости от вашего варианта использования. Вы специально упомянули LocalStorage, следовательно, все предлагают то же самое, но куки будут соответствовать вашему счету, если вы правильно для них истекаете.

  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');
Cookies

Вы можете установить произвольное время истечения, и тогда у вас снова будет выбор выбрать только одну переменную или сохранить ее как JSON.

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

* Файлы cookie будут содержать ограниченный объем данных, как в не очень больших данных (я не думаю, что здесь используется случай, потому что я проверил ваш пример jsfiddle, вы в основном пытаетесь сохранить некоторые данные)

Если вы хотите сохранить JSON данные в файлах cookie, проверьте это Нажмите здесь

* Почему я предлагаю файлы cookie? Многие предприятия уже делают нечто подобное, например, даже после выхода из системы, когда вы заходите на веб-сайт, они отображают ваше имя и просят вас войти, это всего лишь добавление персонализации.

...