javascript - 为什么 filter 方法似乎不像 splice 在这个 todo 应用程序中那样工作?

我在 JS 中有一个 todo 应用程序,具有以下功能:

这是将 id 传递给事件侦听器以删除待办事项的函数的一部分

removeButton.addEventListener('click', function () {
                removeTodo(todo.id)
                renderTodos(todos, filters)
            })

此函数删除待办事项 - 我使用了 2 种方法,findIndex 方式效果很好,它删除了待办事项并呈现新的待办事项 - 我认为我评论过的 filter 方法也可以,但它没有,它确实删除了待办事项,但除非我刷新页面,否则它不会自动更新浏览器中的列表,而 splice 会自动更新,为什么会发生这种情况?它会在 renderTodos 开始读取列表之前等待更新本地存储吗?请注意,在不起作用的示例中,我将 newTodos 传递给 save 函数,我只是将其更改为 todos 以用于 splice 方式。

const removeTodo = function (id) {
const todoIndex = todos.findIndex(function (todo) {
    return todo.id === id
})

if (todoIndex > -1) {
    todos.splice(todoIndex, 1)
}
// newTodos = todos.filter(function (todo) {
//     return todo.id !== id
// })
saveTodos(todos)
}

待办事项列表保存在本地存储中

const saveTodos = function (todos) {
    localStorage.setItem('todos', JSON.stringify(todos))
}

这是信息的渲染功能

const renderTodos = function (todos, filters) {
        const filteredTodos = todos.filter(function (todo) {
            const searchTextMatch = todo.text.toLowerCase().includes(filters.searchText)
            const hideCompletedMatch = !filters.hideCompleted || !todo.completed
            return searchTextMatch && hideCompletedMatch
        })
            
        const todosLeft = filteredTodos.filter(function (todo) {
            return !todo.completed
        })
        document.querySelector('#todos').innerHTML = ''
        document.querySelector('#todos').appendChild(generateSummaryDom(todosLeft))

        filteredTodos.forEach(function (todo) {
            document.querySelector('#todos').appendChild(generateTodoDom(todo))
        })
}

回答1

splice() 改变你正在渲染的 todos 数组,而 filter() 返回一个你没有使用的新数组。

要使其与 filter() 一起使用,您需要从 remove 函数返回 newTodos 并渲染返回的数组,而不是原始的 todos 数组。

removeButton.addEventListener('click', function () {
  const newTodos = removeTodo(todo.id);
  saveTodos(newTodos)
  renderTodos(newTodos, filters);
})

const removeTodo = function (id) {
  return todos.filter(todo => todo.id !== id)
}

const saveTodos = function (todos) {
  localStorage.setItem('todos', JSON.stringify(todos))
}

回答2

重新分配变量没有副作用;重新分配一个标识符对其他地方的标识符没有影响。正在做

newTodos = todos.filter(function (todo) {
    return todo.id !== id
  })
  saveTodos(todos)
}

表示您已将一些结果放入 newTodos 中,而没有对其进行任何其他操作。它不会被存储(或渲染,尽管未显示您的渲染方式)。

传递新过滤的待办事项,并从那里渲染(无论你在做什么) - 不要忘记声明你的变量。

const newTodos = todos.filter(function (todo) {
    return todo.id !== id
  })
  saveTodos(newTodos);
  renderTodos(newTodos);

同时将 renderTodos 从立即侦听器回调中取出。

相似文章

javascript - 将编辑功能添加到待办事项列表

希望在我的待办事项列表中添加编辑功能。我已经设置了按钮,但我对javascript还不是很熟悉,而且我尝试过的方法似乎不起作用。有没有办法像我有我的检查和删除按钮一样添加它,或者我完全错过了什么?任何...

随机推荐

最新文章