#javascript #local-storage #overwrite
#javascript #локальное хранилище #перезапись
Вопрос:
Итак, у меня есть эта функция addToCart
, в Javascript
которой при нажатии на кнопку имя элемента и сумма сохраняются LocalStorage
, а затем я получаю данные innerHTML
. Проблема здесь в том, что всякий раз, когда я нажимаю дважды или более раз на эту кнопку, данные перезаписываются.
Например, я хочу добавить одну куклу в корзину, затем я хочу добавить еще две куклы, затем сохраняется только>
Кукла: 2
но я хочу, чтобы это было
Кукла: 1
Кукла: 2
Мой код:
const lookUpItem = matches.map((match, idx)=>
`<h2 id="name"><span id="${match.itemName}">${match.itemName}</span></h2>
<p>Amount: <span id="am_${idx}">${match.amount1}</span></p>
<button onclick="addToCart('${match.itemName}', 'am_${idx}')" id="add">Add to Cart</button>
</span></small>
</div>`
).join('');
itemList.innerHTML = lookUpItem;
//outPut is id of an <ul> in HTML
const outPutHTML = document.getElementById("outPut");
//nm, am - variables from array.map
//saves line to localStorage and adds line to outputHTML
function addToCart(nm, am) {
{
const itemName = nm;
const amount = document.getElementById(am).innerText;
localStorage.setItem(itemName, amount);
outPutHTML.innerHTML = `${itemName}: ${amount}<br />`;
}
}
//shows all data in Local Storage in outPutHTML
for(let i = 0; i < localStorage.length; i ) {
const name = localStorage.key(i);
const value = localStorage.getItem(name);
outPutHTML.innerHTML = `${name}: ${value} <br />`;
}
Как это решить, я видел, что вы могли бы решить это с JSON.stringtify
помощью, но точно не знаете, как это применить? Я ценю помощь.
Комментарии:
1.
localStorage.key
уже есть подсказки, которые вы сохраняете с помощью ключа. Ключ уникален. У вас не может быть двух записей с одним и тем же ключом. Вам нужно отказаться от этого способа работы. Например, отслеживайте информацию в массиве и сохраняйте массив в локальном хранилище.2. Согласно @trincot, а также, если вы хотите увеличить количество уже существующего товара, тогда вам нужна логика (которой нет), чтобы увидеть, есть ли товар уже в корзине, чтобы увеличить количество. Вероятно, вы захотите сделать это в своей
addToCart
функции.3. Действительно, все, что ему нужно, это сказать
localStorage.setItem("name of item",localStorage.getItem("name of item") "any value");
, я не ошибаюсь?4. Вы не совсем ошибаетесь @OOPSStudio, но предположим, что ключ еще не существует. И поскольку полезная нагрузка представляет собой строку,
она будет объединена.
5. У него может быть простая проверка
if(localStorage.getItem("name of item") !== null)
, чтобы убедиться, что элемент уже существует. А что касается » будет объединяться», да… В этом весь смысл. Он хочет, чтобы «Doll: 2» появлялось после «Doll: 1», он не хочет увеличивать значение на единицу…….. Он хочет объединить.
Ответ №1:
Вы не можете хранить два элемента с одним и тем же ключом в локальном хранилище.
Лучше сначала подумать, как вы будете хранить их в памяти — без учета языкового хранилища.
Например, вы могли бы представить себе такую структуру:
items = [
{ name: "Doll", value: "1" },
{ name: "Doll", value: "2" }
];
И если вам нужно добавить еще один, вы просто делаете
items.push({ name: "Doll", value: "15" });
И как только вы определили свою структуру памяти, вы можете просто записать всю эту структуру в локальное хранилище, используя один жестко запрограммированный ключ:
localStorage.setItem("items", JSON.stringify(items));
И для чтения этой информации в начале вашей страницы:
items = JSON.parse(localStorage.getItem("items") || "[]");
Существует ||
для обработки случая, когда данные еще не присутствуют в локальном хранилище, и в этом случае вы хотите получить пустой массив.
Итак, вот часть вашего адаптированного кода. Комментарии — это ваши комментарии, поэтому вы можете видеть, где код вписывается:
//shows all data in Local Storage in outPutHTML
const items = JSON.parse(localStorage.getItem("items") || "[]");
outPutHTML.innerHTML = items.map(({name, value}) => `${name}: ${value}<br>`)
.join("");
//saves line to localStorage and adds line to outputHTML
function addToCart(name, am) {
const value = document.getElementById(am).innerText;
items.push({name, value});
localStorage.setItem("items", JSON.stringify(items));
outPutHTML.innerHTML = `${name}: ${value}<br>`;
}
Комментарии:
1. «Вы не можете хранить два элемента с одним и тем же ключом в локальном хранилище». Вы можете, если просто преобразуете их в строки, объединяете их, сохраняете эту строку в ключе, а затем
.split()
позже, нет? Я не понимаю, почему решение должно быть сложным, когда на самом деле базовое решение заключается в том, чтобы просто хранить несколько значений в одном ключе… Если я чего-то не упускаю?2. Я хочу сказать, что вы не можете хранить данные в виде двух записей локального хранилища, где каждая запись имеет один и тот же ключ. Конечно, вы можете хранить любую строку, связанную с одним ключом, и эта строка может иметь всю необходимую сложность (что также предлагается в этом ответе). Но это была не моя точка зрения. Мой ответ не слишком сложный. Он просто использует
JSON
кодировку вместо разделителя запятой, что более надежно, когда вы хотите хранить строки с запятой.3. он показывает синтаксическую ошибку для JSON.parse: неожиданный символ в строке 1 столбца 2 данных JSON, и я помещаю ту же строку, я получаю данные в карту массива
4. Это означает, что вы не записывали данные в локальное хранилище в формате JSON. Я вижу, что сначала я упомянул правильный код для этого, но затем не выполнил строковую обработку в последнем блоке кода. Я сделал это сейчас.
5. Спасибо, я использовал метод join для преобразования элементов в строку, при этом вывод stringify HTML показывал ненужные запятые за каждой строкой