为什么刷新后本地存储值清零?

时间:2021-01-05 14:12:36

标签: javascript

const expenseForm = document.querySelector(".tracker-form"),
      expenseName = document.querySelector(".tracker-name"),
      expenseDate = document.querySelector(".tracker-date"),
      expenseAmount = document.querySelector(".tracker-amount"),
      expenseTable = document.querySelector(".tracker-table");

const expenseArray = [];
const EXPENSE_LS = "expense";

function saveExpense() {
    localStorage.setItem(EXPENSE_LS, JSON.stringify(expenseArray));
}

function loadExpense() {
    const loadedExpense = localStorage.getItem(EXPENSE_LS);
    if (loadedExpense !== null) {
        const parsedExpense = JSON.parse(loadedExpense);
        createRow();
        parsedExpense.forEach(expense => {
            paintExpense(expense);
        });
    }
}

function createRow() {
    const tr = document.createElement("tr");
    expenseTable.appendChild(tr);
}

function paintExpense(text) {
    const expenseObj = {};

    function createData(text) {
        const td = document.createElement("td");
        const tr = document.querySelector("tr");
        expenseTable.lastChild.appendChild(td);
    
        td.innerHTML = text;
    
        if (text === expenseName.value && text !== "") {
            expenseObj.name = text;
        } else if (text === expenseDate.value && text !== "") {
            expenseObj.date = text;
        } else if (text === expenseAmount.value && text !== "") {
            expenseObj.amount = text;
        }
    }

    createRow();
    createData(expenseName.value);
    createData(expenseDate.value);
    createData(expenseAmount.value);

    expenseArray.push(expenseObj);

    saveExpense();
}

function handleSubmit(event) {
    event.preventDefault();
    paintExpense();
    expenseName.value = "";
    expenseDate.value = "";
    expenseAmount.value = "";
}

function init() {
    loadExpense();
    expenseForm.addEventListener("submit", handleSubmit);
}

init();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Expense Tracker</title>
    <link href="expense-tracker.css" rel="stylesheet">
</head>
<body>
    <h1>Expense Tracker</h1>
    <h3>Add A New Item</h3>

    <form class="tracker-form">

        <label for="tracker-name">Name: </label>
        <input class="tracker-name" type="text" placeholder="What did you spend?">

        <label for="tracker-date">Date: </label>
        <input class="tracker-date" type="date">

        <label for="tracker-amount">Amount: </label>
        <input class="tracker-amount" type="text">

        <input class="tracker-button" type="submit" value="Add Expense">

    </form>    

    <table class="tracker-table">
        <tr>
            <th scope="col">Name</th>
            <th scope="col">Date</th>
            <th scope="col">Amount</th>
            <th scope="col">Delete</th>
        </tr>
    </table>

    <script src="expense-tracker.js"></script>
</body>
</html>

当我提交表单时,三个输入值在 localStorage 中设置为数组中的一个对象。但是当我刷新页面时,所有的值都清楚了,只剩下对象本身。我认为 loadExpense 函数有问题,但我不知道为什么。我在 google 上搜索了这个问题,几乎他们中的大多数人说在本地存储中设置 stringify 数组并在我得到它时解析它,所以我做到了,但它没有解决这个问题。为什么会这样?

2 个答案:

答案 0 :(得分:1)

问题: 执行 init() 时,它调用 loadExpense(),后者从本地存储读取数据并迭代每个项目,然后调用 paintExpense(expense); 并以费用为参数。

现在在 paintExpense 方法中,传递的费用对象不会用于填充 trtd,而是您正在调用

createData(expenseName.value);
createData(expenseDate.value);
createData(expenseAmount.value); 
expenseArray.push(expenseObj) // <-- Empty object since the fields are empty on load

在这种情况下,所有这些 expenseName, expenseDate, expenseAmount 都是空的,即它们在页面刷新时没有价值。所以在 createData 中,expenseObj 的值没有被设置,这意味着它仍然是空的。

现在行 expenseArray.push(expenseObj); 正在推送数组中的空对象,即 [{}] 最终保存在你 localstorage 中,因此在 localstoray 中,空对象被存储。

解决方案: 使用 expenseObj 中传递的 paintExpense 来填充对象。

示例代码

function loadExpense() {
    const loadedExpense = localStorage.getItem(EXPENSE_LS);
    if (loadedExpense !== null) {
        const parsedExpense = JSON.parse(loadedExpense);
        parsedExpense.forEach(expense => {
            createRow(expense); //<-- Changed to createRow
        });
    }
}

// Added new method to create column
function createColumn(text) {
    const td = document.createElement("td");
    td.innerHTML = text;
    return td;
}



// Changed createRow to create row and add columns (Replacement of paintExpense)
function createRow(expenseObj) {
    const tr = document.createElement("tr");
    tr.append(createColumn(expenseObj.name));
    tr.append(createColumn(expenseObj.date));
    tr.append(createColumn(expenseObj.amount));
    expenseTable.appendChild(tr);
}

// Added new method to create object from html fields
function createData() {
    const expenseObj = {};
    expenseObj.name = expenseName.value;
    expenseObj.date = expenseDate.value;
    expenseObj.amount = expenseAmount.amount;
    return expenseObj;
}

function handleSubmit(event) {
    event.preventDefault();
    const expenseObj = createData(); //<-- Create data from fields
    expenseArray.push(expenseObj) //<-- Push into expense array
    createRow(expenseObj); //<-- Create complete row with columns
    saveExpense(); //<-- Moved Save from paint
    
    expenseName.value = "";
    expenseDate.value = "";
    expenseAmount.value = "";
}

答案 1 :(得分:0)

您应该字符串化您的数据,然后将其放入localStorage

示例:

var testObject = { 'one': 1, 'two': 2, 'three': 3 };

// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));