【问题标题】:Jquery strange chaining of Ajax requestsJquery奇怪的Ajax请求链接
【发布时间】:2020-09-29 19:56:52
【问题描述】:

我有一个名为 project 的 div,它使用 EJS 呈现

EJS的数据中有几个项目,它们是由forEach loop渲染的-所以出现了几个类似的div。

project div 具有id 用于在 Jquery 中进行标识。

此外,它还有 project.nameproject.id 作为 data-*

我遇到的问题:

如果我没有按预期重新加载页面 - 第一次尝试效果很好,元素内部文本会正确更新。 但是在第二次尝试更改另一个项目名称时,两者都更改为以前的值,可以说是两个项目。简而言之 - 新的变化会覆盖以前的所有变化。怎么可能?

链接以查看它在 GIF 中的外观 Imgur

链接请求的奇怪行为 Imgur


  <%userData.forEach(function(project){%>
    <div class="project" id='project <%=project.id%>'>
      <div class="projectHeader">
        <div class="projectTitle">
          <h5 id="projectTitle <%=project.id%>" class="projectName">
            <%=project.name%>
          </h5>
       <div class="projectButtons">
        <span data-toggle="tooltip" data-placement="top" title="Edit Project Title">
          <a data-toggle="modal" data-target="#editProjectTitleModal">
            <i id="editProjectName" class="editProject fas fa-pencil-alt" 
              data-name="<%=project.name%>" data-id="<%=project.id%>"></i>
          </a>
         </span>
       </div>
      </div>
    </div>

project 中的a 标签被点击时,一个简单的模态被调用。

<div class="modal fade" id="editProjectTitleModal" tabindex="-1" aria-labelledby="exampleformModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <form class="" action="" method="">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">Edit Title</h5>
        </div>
        <div class="modal-body">
          <div class="input-group">
            <input id="editProjectNameInput" autocomplete="off" pattern="[a-zA-Z0-9 ].{1,25}" title="1 to 25 characters" class="form-control" aria-label="With textarea" placeholder="Enter new title" required></input>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
          <button type="submit" id="confirmEditProjectName" class="btn btn-primary">Save changes</button>
        </div>
      </form>
    </div>
  </div>
</div>

用于更改project.name 的Jquery 事件处理程序,首先将其发送到数据库并用新名称修改DOM。所以数据库得到了新数据,但是页面没有重新加载,project.name同时发生了变化。

它抓取project-nameproject-id 并发送Ajax 常规发布方法,成功时将元素的内部文本更改为project-name


// Edit Project Title by ID
$(document).on('click', "#editProjectName", function() {
  //Grab Id of the Project
  var editProjectId = $(this).attr('data-id');

 //Fill Modal input with current project.name
  var currentTitle = document.getElementById('projectTitle ' + editProjectId).innerText;
  $("#editProjectNameInput").val(currentTitle)
 
  var url = '/editProjectName';
  $('#confirmEditProjectName').on('click', function(event) {
  //Take new project name from updated modal input
    var newTitle = $("#editProjectNameInput").val();
  //If they are same - alert
    if (currentTitle === newTitle) {
      event.preventDefault();
      alert("New Title should be different")
    } else {
      event.preventDefault();
      if (newTitle.length > 1 && newTitle.length <= 25) {
        $.ajax({
          type: "POST",
          url: url,
          data: {
            projectName: newTitle,
            projectID: editProjectId
          },
          success: function(result) {
     //Hide modal and change element inner text to new value
            $("#editProjectTitleModal").modal('hide')
        document.getElementById('projectTitle ' + editProjectId).innerText = newTitle;

      },
      error: function(err) {
        console.log(err);
      }
    })
  }
    }
  })
})

【问题讨论】:

  • 首先,ID 中不能有空格:ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
  • 另外,ID 必须是唯一的,但在您的循环中,您使用的是 id="editProjectName"
  • @imvain2 我该如何解决这个问题?也许只是通过函数 onClick?

标签: javascript html jquery dom


【解决方案1】:

我从 ID 中删除了空格,并从使用 #editProjectName 的 ID 更改为仅使用 editProject 的该对象上已经存在的类。

<%userData.forEach(function(project){%>
    <div class="project" id='project<%=project.id%>'>
      <div class="projectHeader">
        <div class="projectTitle">
          <h5 id="projectTitle<%=project.id%>" class="projectName">
            <%=project.name%>
          </h5>
       <div class="projectButtons">
        <span data-toggle="tooltip" data-placement="top" title="Edit Project Title">
          <a data-toggle="modal" data-target="#editProjectTitleModal">
            <i class="editProject fas fa-pencil-alt" 
              data-name="<%=project.name%>" data-id="<%=project.id%>"></i>
          </a>
         </span>
       </div>
      </div>
    </div>

// Edit Project Title by ID
$(document).on('click', ".editProject", function() {
  //Grab Id of the Project
  var editProjectId = $(this).attr('data-id');

 //Fill Modal input with current project.name
  var currentTitle = document.getElementById('projectTitle' + editProjectId).innerText;
  $("#editProjectNameInput").val(currentTitle)
 
  var url = '/editProjectName';
  $('#confirmEditProjectName').on('click', function(event) {
  //Take new project name from updated modal input
    var newTitle = $("#editProjectNameInput").val();
  //If they are same - alert
    if (currentTitle === newTitle) {
      event.preventDefault();
      alert("New Title should be different")
    } else {
      event.preventDefault();
      if (newTitle.length > 1 && newTitle.length <= 25) {
        $.ajax({
          type: "POST",
          url: url,
          data: {
            projectName: newTitle,
            projectID: editProjectId
          },
          success: function(result) {
     //Hide modal and change element inner text to new value
            $("#editProjectTitleModal").modal('hide')
        document.getElementById('projectTitle' + editProjectId).innerText = newTitle;

      },
      error: function(err) {
        console.log(err);
      }
    })
  }
    }
  })
})

【讨论】:

  • @imvain2谢谢。我想我明白了,为了防止像我这样的情况,最好按类调用事件,对吧?
  • @imavain2 我用你的 sn-p 更新了我的代码。我已经想通了-如果我不更改名称-而只是单击以编辑并关闭输入模式,则发布请求会以某种方式堆叠在一起。因此,每个记录的项目 ID 都会被保存,并且在最终发送时 - 所有 ID 都会受到影响并更改其名称。不知道如何继续。
【解决方案2】:

经过一些研究,我发现一旦调用on('click'),它就会开启,直到页面重新加载。

感谢这个问答:

https://stackoverflow.com/a/6121501/13541013

我发现 - on('click') 事件应该通过调用 $(this).off() 来切换 offthis 是事件)

在我的情况下,我必须在之后创建$(this).off()

$(document).on('click', "#editProjectName", function() {
$(this).off() ... further code

并且必须为脚本中的每个 on('click') 事件完成。

【讨论】:

    猜你喜欢
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多