JavaScript:单击';编辑';按钮时,console.log显示;“未定义”;
我使用的是Rails API后端和JavaScript前端。我有一个表单和一个材质列表,我正在尝试使每个材质都可编辑。我现在设置了一个点击事件,试图找到我点击的材料的ID,但是console.log显示“undefined” 有人能帮我吗?当我点击一个材料时,它会显示我正在点击的材料 index.js文件:JavaScript:单击';编辑';按钮时,console.log显示;“未定义”;,javascript,Javascript,我使用的是Rails API后端和JavaScript前端。我有一个表单和一个材质列表,我正在尝试使每个材质都可编辑。我现在设置了一个点击事件,试图找到我点击的材料的ID,但是console.log显示“undefined” 有人能帮我吗?当我点击一个材料时,它会显示我正在点击的材料 index.js文件: const materialIndex = "http://localhost:3000/api/v1/materials" const categoryIndex =
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 = []
类材料{
建造商(材料、材料属性){
this.id=material.id
this.name=materialAttributes.name
this.description=materialAttributes.description
this.url=materialAttributes.url
this.category=materialAttributes.category
材料。全部。推(这个)
}
renderMaterialCard(){
返回`
${this.name}
${this.description}
${this.category.title}
编辑
`
}
静态findById(id){
返回此.all.find(material=>material.id==id)
}
renderPatchForm(){
返回`
编辑资源
名称
描述
${this.description}
统一资源定位地址
类别
刑事司法改革
保释金
服装
组织机构
互助
募捐者
请愿书
文章
艺术家
一款图片分享应用
`
}
}
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)
}
我会尝试使用filter而不是find,工作检查的另一件事是material.id的类型和id的类型。如果它们是不同的类型,比如material.id='1',id是int 1,您可以使用双等于,material.id==id
static findById(id) {
return this.all.filter(material => material.id == id)
}
我注意到您正在向材质容器添加事件侦听器。这将在内部单击任何内容时触发,并且这些目标上不会有
数据id
属性。您可能要做的是查找所单击目标的。最近(“[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或找到其他方式来委派事件。为什么要在id上使用
parseInt
,只是好奇当您进行调试时,e.target.dataset.id
和Material.all
?。过滤器没有帮助,但删除了一个“=”选项!非常感谢。令人惊讶的是,这使它们都出现在控制台中。非常感谢