javascript - 在更改其属性后渲染数组项
问题描述
在对数组中的元素进行更改后,我在重新渲染数组中的项目时遇到问题。无论我是通过推入添加还是通过拼接删除,当数组在页面上再次呈现时,就像更多的项目被添加到数组中一样。因此,如果我推入数组,则会添加项目,但旧项目会被复制到数组中。当我删除项目时会发生类似的事情。该项目看起来已被删除,但数组中的元素显示在页面上,然后它们被复制并且被拼接的项目消失了。
我试图避免使用 location.reload('/edit.html') 来刷新页面。一种作弊。它似乎有效,但我正在尝试使用我的renderIngredients
功能刷新页面。toggleIngredient
当我检查一个项目时,该功能还会复制项目列表。
import { initializeEditPage, generateLastEdited } from './views'
import { updateRecipe, removeRecipe, saveRecipes, getRecipes, createIngredient } from './recipes'
const titleElement = document.querySelector('#recipe-title')
const bodyElement = document.querySelector('#recipe-body')
const removeElement = document.querySelector('#remove-recipe')
const addElement = document.querySelector('#add-recipe')
const dateElement = document.querySelector('#last-updated')
const addIngredient = document.querySelector('#new-ingredient')
const recipeStatus = document.querySelector('#recipe-status')
const recipeId = location.hash.substring(1)
const recipeOnPage = getRecipes().find((item) => item.id === recipeId)
titleElement.addEventListener('input', (e) => {
const recipe = updateRecipe(recipeId, {
title: e.target.value
})
dateElement.textContent = generateLastEdited(recipe.updatedAt)
})
bodyElement.addEventListener('input', (e) => {
const recipe = updateRecipe(recipeId, {
body: e.target.value
})
dateElement.textContent = generateLastEdited(recipe.updatedAt)
})
addElement.addEventListener('click', () => {
saveRecipes()
location.assign('/index.html')
})
removeElement.addEventListener('click', () => {
removeRecipe(recipeId)
location.assign('/index.html')
})
addIngredient.addEventListener('submit', (e) => {
const text = e.target.elements.text.value.trim()
e.preventDefault()
if (text.length > 0) {
createIngredient(recipeId, text)
e.target.elements.text.value = ''
}
renderIngredients(recipeId)
saveRecipes()
//location.reload('/edit.html')
})
const removeIngredient = (text) => {
const ingredientIndex = recipeOnPage.ingredients.findIndex((ingredient)=> ingredient.text === text)
if (ingredientIndex > -1) {
recipeOnPage.ingredients.splice(ingredientIndex, 1)
}
saveRecipes()
renderIngredients(recipeId)
//location.reload('/edit.html')
}
const toggleIngredient = (text) => {
const ingredient = recipeOnPage.ingredients.find((ingredient) => ingredient.text === text)
if (ingredient.included) {
ingredient.included = false
} else {
ingredient.included = true
}
//location.reload('/edit.html')
}
const ingredientSummary = (recipe) => {
let message
const allUnchecked = recipeOnPage.ingredients.every((ingredient) => ingredient.included === false)
const allChecked = recipeOnPage.ingredients.every((ingredient) => ingredient.included === true)
if (allUnchecked) {
message = `none`
} else if (allChecked) {
message = `all`
} else {
message = `some`
}
return `You have ${message} ingredients for this recipe`
}
const generateIngredientDOM = (ingredient) => {
const ingredientEl = document.createElement('label')
const containerEl = document.createElement('div')
const checkbox = document.createElement('input')
const ingredientText = document.createElement('span')
const removeButton = document.createElement('button')
recipeStatus.textContent = ingredientSummary(recipeOnPage)
// Setup ingredient container
ingredientEl.classList.add('list-item')
containerEl.classList.add('list-item__container')
ingredientEl.appendChild(containerEl)
// Setup ingredient checkbox
checkbox.setAttribute('type', 'checkbox')
checkbox.checked = ingredient.included
containerEl.appendChild(checkbox)
// Create checkbox button in ingredient div
checkbox.addEventListener('click', () => {
toggleIngredient(ingredient.text)
saveRecipes()
renderIngredients(recipeId)
})
// Setup ingredient text
ingredientText.textContent = ingredient.text
containerEl.appendChild(ingredientText)
// Setup the remove button
removeButton.textContent = 'remove'
removeButton.classList.add('button', 'button--text')
ingredientEl.appendChild(removeButton)
// Create remove button in ingredient div
removeButton.addEventListener('click', () => {
removeIngredient(ingredient.text)
saveRecipes()
renderIngredients(recipeId)
})
return ingredientEl
}
const renderIngredients = (recipeId) => {
// Grab the ingredient display from the DOM
const ingredientList = document.querySelector('#ingredients-display')
const recipe = getRecipes().find((item) => {
return item.id === recipeId
})
// Iterate through the list of ingredients on the page and render all items from recipeDOM
recipe.ingredients.forEach((ingredient) => {
const recipeDOM = generateIngredientDOM(ingredient)
ingredientList.appendChild(recipeDOM)
})
}
renderIngredients(recipeId)
我相信这个问题源于我的 renderIngredients 函数,但我不知道如何解决它。同样,当我刷新页面时,我想要显示的结果,但我想避免使用location.reload
. 我希望该removeIngredient
功能可以通过单击按钮来删除成分,并且页面会使用该renderIngredients
功能刷新。还期望该toggleIngredient
功能仅在我检查的成分旁边显示一个复选框,但这不是正在发生的事情。当我使用该addIngredient
功能时,同样的事情发生了,正在添加成分,但是已经在页面上的成分正在被复制。
解决方案
我猜你想在再次添加元素之前清除列表:
ingredientList.innerHTML = "";
推荐阅读
- reactjs - React 美丽的 DnD- 嵌套列表,但无需在父列表之间拖动
- node.js - 如何处理电子邮件并将其转发到目的地
- javascript - 如何使用浏览器后退按钮关闭覆盖?
- max - Oracle中的最大sql语句
- swift - 是否可以在触控板上模拟三重触控滑动?- 斯威夫特
- django - 如何在 django 模板 img 元素中显示多个图像
- python - 当我使用 python 模块(如 pytube 或任何其他模块)时,应用程序总是失败
- react-native - 如何让孩子阻止ScrollView滚动
- python - 使用检索模型对第一遍检索中的前 100 个文档进行重新排序
- pymc3 - 分层(三层深)贝叶斯pymc3模型