Рендеринг элементов массива после внесения изменений в его свойства - PullRequest
0 голосов
/ 15 января 2019

У меня проблема с повторным рендерингом элементов в массиве после внесения изменений в элементы в массиве. Независимо от того, добавляю ли я путем нажатия или удаления путем сращивания, когда массив снова отображается на странице, все равно, что в массив добавляется больше элементов. Поэтому, если я нажимаю на массив, элемент добавляется, но старые элементы затем дублируются в массив. Нечто подобное происходит, когда я удаляю предметы. Элемент выглядит удаленным, но элементы, которые были в массиве, отображаются на странице, затем они дублируются, и элемент, который был объединен, исчезает.

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

1 Ответ

0 голосов
/ 15 января 2019

Полагаю, вы хотите очистить список, прежде чем добавлять элементы снова:

ingredientList.innerHTML = "";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...