簡體   English   中英

JavaScript:單擊“編輯”按鈕時,console.log 顯示“未定義”

[英]JavaScript: when clicking on 'edit' button, the console.log reads “undefined”

我正在使用 Rails API 后端和 JavaScript 前端。 我有一個表單和一個材質列表,我正在嘗試使每個材質都可編輯。 我現在設置了一個點擊事件,試圖找到我點擊的材料的 ID,但 console.log 顯示“未定義”。

有人可以幫助我,所以當我點擊一個材質時,它會顯示我點擊的材質嗎?

index.js 文件:

const materialIndex = "http://localhost:3000/api/v1/materials"
const categoryIndex = "http://localhost:3000/api/v1/categories"

document.addEventListener('DOMContentLoaded', () => {
    getMaterials()

    const createMaterialForm = document.querySelector("#create-material-form")

    createMaterialForm.addEventListener("submit", (e) => createFormHandler(e))

    const materialContainer = document.querySelector('#material-container')
    materialContainer.addEventListener('click', e => {
        //debugger
        const id = parseInt(e.target.dataset.id)
        const material = Material.findById(id)
        console.log(material)
    })

})

function getMaterials() {
    fetch(materialIndex) //get request
    .then(response => response.json())
    .then(materials => {
        materials.data.forEach(material => {
            let newMaterial = new Material(material, material.attributes)
            //creating new instance of material class, goes to constructor and gets pushed into an array
            document.querySelector('#material-container').innerHTML += newMaterial.renderMaterialCard()
        })
        // want to create category cards, where each resource populates in each category card once added //
    })
}

function createFormHandler(e) { //grabs all values of materials submitted by user
    e.preventDefault()
    const nameInput = document.querySelector('#input-name').value
    const descriptionInput = document.querySelector('#input-description').value
    const urlInput = document.querySelector('#input-url').value
    const categoryId = parseInt(document.querySelector('#categories').value)
    postFetch(nameInput, descriptionInput, urlInput, categoryId)
}

function postFetch(name, description, url, category_id) {
    const bodyData = {name, description, url, category_id}
    fetch(materialIndex, {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify(bodyData)
    })
    .then(response => response.json())
    .then(material => {
        const materialData = material.data
        let newMaterial = new Material(materialData, materialData.attributes)
        
        document.querySelector('#material-container').innerHTML += newMaterial.renderMaterialCard()
    })

    //patch or delete request
    
}

material.js 文件:

class Material {
    constructor(material, materialAttributes) {
        this.id = material.id
        this.name = materialAttributes.name
        this.description = materialAttributes.description
        this.url = materialAttributes.url
        this.category = materialAttributes.category
        Material.all.push(this)
    }

    renderMaterialCard() {
        return `
            <div data-id=${this.id}>
            <h3>${this.name}</h3>
            <p>${this.description}</p>
            <p><small><a href="${this.url}">${this.url}</a></small></p>
            <p>${this.category.title}</p>
            <button data-id=${this.id}>edit</button>
            </div>
            <br><br>`
    }

    static findById(id) {
        return this.all.find(material => material.id === id)
    }


    renderPatchForm() {
        return `
            <form data-id=${this.id} >
                <h3>Edit the Resource</h3>

                <label>Name</label>
                <input id='input-name' type="text" name="name" value="${this.name}" class="input-name">
                <br><br>

                <label>Description</label>
                <textarea id='input-description' name="description" rows="8" cols="80" value="">${this.description}</textarea>
                <br><br>

                <label>URL</label>
                <input id='input-url' type="text" name="url" value="${this.url}" class="input-text">
                <br><br>

                <label>Category</label>
                <select id="categories" name="categories" value="${this.category.name}">
                    <option value="1">Criminal Justice Reform</option>
                    <option value="2">Bail Funds</option>
                    <option value="3">Clothing</option>
                    <option value="4">Organizations</option>
                    <option value="5">Mutual Aid</option>
                    <option value="6">Fundraisers</option>
                    <option value="7">Petitions</option>
                    <option value="8">Articles</option>
                    <option value="9">Artists</option>
                    <option value="10">Instagram</option>
                </select>
                <br><br>

                <input id='edit-button' type="submit" name="submit" value="Edit Material" class="submit">
            </form> `
  }
}

Material.all = []

index.html 文件:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Beneficial Resources</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
        <script type="text/javascript" src="src/material.js"></script>
        <script type="text/javascript" src="src/index.js"></script>
    </head>
    <body>

        <div class="form-container">
            <form id="create-material-form">
                <center>
                <h3>Add a new Resource</h3>

                <input id='input-name' type="text" name="name" value="" placeholder="Enter the Resource name" class="input-text">
                <br><br>
                <textarea id='input-description' name="description" rows="8" cols="80" value="" placeholder="Enter the description of your Resource..."></textarea>
                <br><br>
                <input id="input-url" type="text" name="url" value="" placeholder="Enter the URL of your Resource..." class="input-text">
                <br>

                <h3>What Category is your Resource?</h3>
                <select id="categories" name="categories">
                    <option value="1">Criminal Justice Reform</option>
                    <option value="2">Bail Funds</option>
                    <option value="3">Clothing</option>
                    <option value="4">Organizations</option>
                    <option value="5">Mutual Aid</option>
                    <option value="6">Fundraisers</option>
                    <option value="7">Petitions</option>
                    <option value="8">Articles</option>
                    <option value="9">Artists</option>
                    <option value="10">Instagram</option>
                </select>
                <br>

                <input id="create-button" type="submit" name="submit" value="Add New Resource" class="submit">

            </form>
        </center>
            <br>
            <br>
        </div>

        <div id="material-container">

        </div>

        <div id="update-material">

        </div>
        
    </body>
</html>

只是看着你的代碼

    static findById(id) {
        return this.all.find(material => material.id === id)
    }

我會嘗試使用過濾器而不是查找,另一件工作檢查是 material.id 的類型和 id 的類型。 如果它們是不同的類型,例如 material.id = '1' 並且 id 為 int 1,則您可以使用雙等號,material.id == id。

    static findById(id) {
        return this.all.filter(material => material.id == id)
    }

我注意到您正在向材質容器添加一個事件偵聽器。 這將在點擊內部的任何內容時觸發,並且這些目標上不會有data-id屬性。 您可能想要做的是找到點擊的目標的.closest('[data-id]')

const materialContainer = document.querySelector('#material-container')
    materialContainer.addEventListener('click', e => {
        //debugger
        const id = parseInt(e.target.closest('[data-id]').dataset.id);
        const material = Material.findById(id)
        console.log(material)
    })

這在 IE11 或更舊的瀏覽器中不起作用,因為它們沒有實現.closest()

如果您需要支持較舊的瀏覽器,您可能需要使用 polyfill 或找出其他方法來委托事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM