【问题标题】:Can't delete newly created list item without refreshing the page and trying again ES6无法在不刷新页面并重试 ES6 的情况下删除新创建的列表项
【发布时间】:2018-12-04 09:10:49
【问题描述】:

一些背景:我正在尝试完成我最小的笔记应用程序的删除功能的构建。

每次我创建一个新笔记时,它都会出现在我的笔记列表的末尾。但是,如果我尝试删除新创建的笔记,它将无法正常工作。我必须刷新页面并重试它才能工作。

我不断收到这两个错误:

“未捕获的 TypeError:无法在 HTMLUListElement 处读取 null 的属性 'parentNode'。”

“删除http://localhost:3000/api/v1/notes/undefined404(未找到)”

否则,我可以毫无问题地删除任何其他笔记。

这是我的js代码:

  // display list of notes on the side

  const noteContainer = document.querySelector(".column is-one-quarter")
  const noteList = document.querySelector(".menu-list")

  fetch('http://localhost:3000/api/v1/notes')
  .then(function(response) {
    return response.json();
  })
  .then(function(notes) {
    notes.forEach(function(note) {
      noteList.innerHTML += `<li id="list-item" data-id=${note.id}><a id="note" data-id=${note.id} class="menu-item">${note.title}</a><i id="delete" data-id=${note.id} class="fas fa-minus-circle has-text-grey-light hvr-grow"></i></li>`
    })
  })

  // display details of each note

    const noteDetail = document.querySelector(".note-detail")

    noteList.addEventListener('click', function(event) {
      if (event.target.className === "menu-item") {
        fetch(`http://localhost:3000/api/v1/notes/${event.target.dataset.id}`)
        .then(function(response) {
          return response.json()
        })
        .then(function(note) {
            noteDetail.innerHTML = `<h1 contenteditable="true" id="title" data-id=${note.id} class="subtitle is-2">${note.title}</h1><p contenteditable="true" id="body" data-id=${note.id} class="subtitle is-6">${note.body}</p><a id="save" data-id=${note.id} class="button is-small">Save</a>`
        })
       }
      })

    // i should be able to edit the title and body of a note when i click
    // on it and it should save when i click on the button.

         noteDetail.addEventListener('click', function(event) {
           if (event.target.id === "save") {
             const noteId = event.target.dataset.id
             const editTitleInput = document.querySelector(`h1[data-id="${noteId}"]`)
             const editBodyInput = document.querySelector(`p[data-id="${noteId}"]`)
             const singleNote = document.querySelector(`a[data-id="${noteId}"]`)
             fetch(`http://localhost:3000/api/v1/notes/${noteId}`, {
               method: "PATCH",
               headers: {
                 'Content-Type': 'application/json',
                 'Accepts': 'application/json'
               },
               body: JSON.stringify({
                 title: editTitleInput.innerText,
                 body: editBodyInput.innerText
               })
             }).then(function(response) {
               return response.json()
             }).then(function(note) {
                    singleNote.innerText = editTitleInput.innerText
                })
              }
            })


    // when i click on the button, a form with a title and body input
    // should display on the right.

      const newNoteButton = document.querySelector("#create")

      newNoteButton.addEventListener('click', function(event) {
          fetch("http://localhost:3000/api/v1/notes")
          .then(function(response) {
            return response.json()
          })
          .then(function(note) {
            noteDetail.innerHTML = `<input id="title" class="input subtitle is-5" type="text" placeholder="Title">
            <textarea id="body" class="textarea subtitle is-5" placeholder="Body" rows="10"></textarea><a id="add" class="button has-text-black" style="margin-left: 594px;">Add Note</a>`

            // when i click on 'add button', a new note with a title and body
            // should be created and added to the list of notes.

            const noteTitleInput = document.querySelector("#title")
            const noteBodyInput = document.querySelector("#body")
            const addNoteButton = document.querySelector("#add")

            addNoteButton.addEventListener('click', function(event) {
              // event.preventDefault()
              fetch('http://localhost:3000/api/v1/notes', {
                method: "POST",
                headers: {
                  'Content-Type': 'application/json',
                  'Accepts': 'application/json'
                },
                body: JSON.stringify({
                  title: noteTitleInput.value,
                  body: noteBodyInput.value
                })
              }).then(function(response) {
                return response.json()
              }).then(function(note) {
                noteList.innerHTML += `<li data-id=${note.id}><a id="note" data-id=${note.id} class="menu-item">${note.title}</a><i id="delete" class="fas fa-minus-circle has-text-grey-light hvr-grow"></i></li>`
              })
            })

          })
        })


        // i should be able to delete a note when i click on the button.

        noteList.addEventListener('click', function(event) {
          // event.preventDefault()
          if (event.target.id === "delete") {
            const noteId = event.target.dataset.id
            // const noteListItem = document.querySelector("#list-item")
            const noteListItem = document.querySelector(`li[data-id="${noteId}"]`)
            const singleNote = document.querySelector(`a[data-id="${noteId}"]`)
            fetch(`http://localhost:3000/api/v1/notes/${noteId}`, {
              method: "DELETE",
            })
            // debugger
           // lastNote = noteList.lastElementChild
           // noteList.removeChild(lastNote)
           // singleNote.parentElement.remove()
           noteListItem.parentNode.removeChild(noteListItem)
           noteDetail.innerHTML = ""
           }
         })

这是我的html代码:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css">
    <link href="css/hover.css" rel="stylesheet" media="all">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
    <link rel="stylesheet" href="css/note.css">
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>

    <h1 class="title is-1">Jot</h1>

<div class="columns">

  <div class="column is-one-quarter">
    <p class="menu-label" style="font-size:15px;">
      Notes <i id="create" class="fas fa-plus-circle has-text-grey-light hvr-grow" style="margin-left: 10px; width: 20px; height: 30px; font-size: 24px;"></i>
    </p>
      <ul class="menu-list">

      </ul>
 </div>

  <div class="column is-three-fifths">
    <div class="note-detail">

    </div>
  </div>

  <div class="column">

  </div>

</div>

    <script src="index.js"></script>
  </body>
</html>

任何帮助将不胜感激。 :)

【问题讨论】:

  • 我仍然没有运气试图解决这个问题。有人可以帮忙吗?
  • 第一个代码块第 95/96 行 note 的数据结构是什么?你能分享一下吗?
  • @MHornbacher 我相信这是一个对象。

标签: javascript html dom ecmascript-6 fetch


【解决方案1】:

你在这两行嵌套字符串:

const noteListItem = document.querySelector(`li[data-id="${noteId}"]`)
const singleNote = document.querySelector(`a[data-id="${noteId}"]`)

您的模板文字正在创建一个字符串,并且您将其放在引号内。例如,如果您的 noteId12。你的代码最终是这样的:

const noteListItem = document.querySelector("li[data-id="'12'"]")
const singleNote = document.querySelector("a[data-id="'12'"]")

我不能 100% 确定这是你的问题,但这是我首先想到的。

您可以查看 MDN 以更新您的 Template literals (Template strings)

【讨论】:

  • 我不认为这正是问题所在。我想要做的是通过数据 id 获取特定的注释,所以我使用了我认为被称为属性选择器的东西。这是stackoverflow上帮助我编辑功能的人所做的,以检索特定笔记的特定标题和正文
猜你喜欢
  • 2019-11-16
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多