【问题标题】:deleting mysql records with ajax用ajax删除mysql记录
【发布时间】:2009-02-09 22:22:20
【问题描述】:

我想知道从实时数据库中删除记录并立即刷新页面的最佳方法。目前我正在使用 ajax,使用以下 javascript 方法:

function deleterec(layer, pk) {
   url = "get_records.php?cmd=deleterec&pk="+pk+"&sid="+Math.random();
   update('Layer2', url);
}

如果 php 页面上的 cmd=deleterec,则在主键 = pk 的地方进行删除。这工作正常,因为记录被删除,但页面没有更新。

我的更新方法很简单:

function update(layer, url) {
    var xmlHttp=GetXmlHttpObject(); //you have this defined elsewhere

    if(xmlHttp==null) {
        alert("Your browser is not supported?");
    }

    xmlHttp.onreadystatechange = function() {
        if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
            document.getElementById(layer).innerHTML=xmlHttp.responseText;
        } else if (xmlHttp.readyState==1 || xmlHttp.readyState=="loading") {
            document.getElementById(layer).innerHTML="loading";
        }

       //etc
    }

    xmlHttp.open("GET",url,true);
    xmlHttp.send(null);
}

如何删除或更改记录,以及更新页面。

目前,我的 ajax 框架通过将数据传递给 javascript 更新方法来工作,该方法适用于选择不同的查询以显示在不同的层中。

我想添加删除功能,或以某种方式更改记录。

我想知道是否可以在单击链接执行查询然后调用我的更新方法并刷新 tge 页面时。考虑到我的更新方法,有什么简单的方法可以做到这一点吗?

如果可能,我想避免重写我的更新方法。

最简单的方法是在执行 mysql 查询后让 php 页面(仅在层中)重新加载吗?

或者创建一个新的“alterstatus”方法,将delete或watch作为参数传递,并让php执行相应的查询然后更新页面?

edit:链接是这样生成的。 deleterec 将从生成的附加链接中调用。

{

$pk = $row['ARTICLE_NO'];

echo '<tr>' . "\n"; 

    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n"; 

echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n"; 

echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['ARTICLE_NAME'].'</a></td>' . "\n"; 


echo '<td><a href="#" onclick="deleteRec(\'Layer2\', \'' . $pk . '\')">'.$row['ARTICLE_NAME'].'</a></td>' . "\n"; 

echo '</tr>' . "\n"; 

}

edit:update方法不能修改,因为它被需要层的updateByPk和updateBypg方法使用。

【问题讨论】:

  • 一个建议:如果可能,请不要使用 GET,而是使用 DELETE 请求请求,这样您就不会因为有人在浏览器中键入正确构造的 URL 而导致删除。
  • 您应该能够使用 AJAX 发送 DELETE 请求。 POST 也可以。不过,DELETE 更加 RESTful。

标签: php javascript ajax


【解决方案1】:

如果不深入研究您的代码细节,我不知道有任何方法可以在不进行往返(AJAX 或页面导航)的情况下从服务器端数据库更新/删除。不过,我建议使用 JavaScript 框架(如 jQuery 或其他)来处理 AJAX 和 DOM 操作。从理论上讲,这应该可以减轻 Thinbs 客户端的任何跨浏览器故障排除。

【讨论】:

  • 我同意使用框架而不是滚动您自己的 AJAX。
  • +1 用于 jQuery。每天都有一个框架可以挽救我的生命。
  • 如果我想使用 jQuery,那么我会的。该答案与实际问题无关。
  • -1 自动对 jQuery 膝盖投反对票。问题中的任何内容都不需要框架;没有与“Node.removeChild”相关的跨浏览器困难。这仍然是投票率最高的答案,这是对 SO 的 jQuery 崇拜的悲哀反映。
  • 我几乎不会称它为“膝跳动”,但无论如何。作为处理过许多跨浏览器 JS/DOM 问题的人,我会推荐 anything 来解决不一致的问题。对不起,你不喜欢我的回答,显然有些人喜欢。如果您有答案,您总是可以提交更好的答案吗?
【解决方案2】:

当您说“立即更新”时,我认为您的意思是通过 Javascript 更新文档。 Ajax 和页面刷新不能一起使用。

您如何显示现有的数据行?例如,假设您是这样列出它们的:

<div id="row1">row 1</div>
<div id="row2">row 2</div>

其中 row1 和 row2 是数据库中的行,主键分别为 1 和 2。使用一个简单的 javascript 函数从 DOM 中删除关联的 div:

function deleterec(pk) {
    url = "get_records.php?cmd=deleterec&pk="+pk+"&sid="+Math.random();
    update(pk, url);
}

function update(pk, url) {
    var xmlHttp=GetXmlHttpObject(); //you have this defined elsewhere

    if(xmlHttp==null) {
        alert("Your browser is not supported?");
    }

    xmlHttp.onreadystatechange = function() {
        if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
            document.getElementById(layer).innerHTML=xmlHttp.responseText;
            removeDomRow(pk); //You may wish to check the response here
        } else if (xmlHttp.readyState==1 || xmlHttp.readyState=="loading") {
            document.getElementById(layer).innerHTML="loading";
        }
    }
    xmlHttp.open("GET",url,true);
    xmlHttp.send(null);
}

以及以下函数来操作 DOM:

function removeDomRow(pk){
        var row = document.getElementById('row' + pk);
        row.parentNode.removeChild(row);
}

如果您使用的是表格:

<tr id="row1">
    <td>row 1</td>
</tr>
<tr id="row2">
    <td>row 2</td>
</tr>

你可以使用:

 function removeDomRow( id ) { // delete table row
    var tr = document.getElementById( 'row' + id );
    if ( tr ) {
      if ( tr.nodeName == 'TR' ) {
        var tbl = tr; // Look up the hierarchy for TABLE
        while ( tbl != document && tbl.nodeName != 'TABLE' ) {
          tbl = tbl.parentNode;
        }
        if ( tbl && tbl.nodeName == 'TABLE' ) {
          while ( tr.hasChildNodes() ) {
            tr.removeChild( tr.lastChild );
          }
          tr.parentNode.removeChild( tr );
        }
      }
    }

关于 raccoonbear 的观点,如果您要使用 Qjuery 之类的框架,事情会容易得多:

$('#row'+id).remove();

【讨论】:

  • 这很有趣,可能就是我要找的。这些行存储为表格行,而不是单独的 div,所以这仍然可以工作,还是只能与 div 一起工作?
  • 感谢 Ademuk 的更新。但是,没有一个表行有 id。它们是从 php 中的 for 循环自动生成的,所以我认为这个解决方案行不通。
  • 您不能在此循环输出中添加和 ID?你从哪里调用 deleterec()?
  • deleterec 添加到循环输出中生成的链接中。我已经编辑了我的问题以显示链接的生成。
  • 至少,您应该将其设为 POST 类型的请求,因为它有副作用。
【解决方案3】:

我想知道是否可以在单击链接执行查询然后调用我的更新方法并刷新 tge 页面时。考虑到我的更新方法,有什么简单的方法可以做到这一点吗?

那么,你为什么不直接提交一个表单呢?

【讨论】:

    【解决方案4】:

    你有两个选择:

    • 进行完整的往返,即在您知道项目已成功删除之前不要更新 UI,或者

    • 欺骗你的用户

    如果操作的结果有问题且重要,请使用第一个选项。如果您对结果有信心,并且人们不需要知道细节,请使用第二个。

    真的,没有什么比被成功欺骗更能让人开心的了。

    【讨论】:

    • Facebook 通过撒谎来做到这一点,然后在请求失败时显示警告(并恢复 UI 更改)。
    【解决方案5】:

    我不会使用 HTTP GET 方法从数据库中删除记录,我会使用 POST。而且我不会使用 Ajax,因为您正在寻找的交互显然是 同步 :删除然后更新。我会使用常规提交(JS 或 HTML)。

    也就是说,如果您真的致力于使用 XHR,剩下的唯一解决方案是根据 Renzo Kooi 建议的服务器响应进行回调。

    【讨论】:

      【解决方案6】:

      您可以创建一个在客户端负责更新屏幕的回调。您可以在 XHR 函数中执行此操作。

          function update(layer, url) {
              var xmlHttp=GetXmlHttpObject(),
                   callbackFn = function(){ 
                        /* ... do thinks to reflect the update on the user screen,
                               e.g. remove a row from a table ...*/
                       };
      
              if(xmlHttp==null) {
                  alert("Your browser is not supported?");
              }
      
              xmlHttp.onreadystatechange = function() {
                  if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
                      /* if the server returns no errors run callback 
                         (so server should send something like 'ok' on successfull
                         deletion 
                      */
                      if (xmlHttp.responseText === 'ok') {
                            callback();
                      }
              //=>[...rest of code omitted]
      

      【讨论】:

      • 嗨,Renzo,你能用我的 deleterec 示例展示我如何使用它吗?
      • 我正在考虑一个代码示例。目前很忙,所以可能需要一些时间。
      【解决方案7】:

      删除和更新 DOM:

      echo '<td><a href="#" onclick="deleteRec(this, \'' . $pk . '\')">'.$row['ARTICLE_NAME'].'</a></td>' . "\n"; 
      
      function deleterec(row, pk) {
          var rowId = row.parentNode.parentNode.rowIndex;
          url = "get_records.php?cmd=deleterec&pk="+pk+"&sid="+Math.random();
          update(rowId, url);
      }
      
      function update(rowId, url) {
          var xmlHttp=GetXmlHttpObject(); //you have this defined elsewhere
      
          if(xmlHttp==null) {
              alert("Your browser is not supported?");
          }
      
          xmlHttp.onreadystatechange = function() {
              if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
                  document.getElementById(layer).innerHTML=xmlHttp.responseText;
                  deleteRow(rowId); //You may wish to check the response here
              } else if (xmlHttp.readyState==1 || xmlHttp.readyState=="loading") {
                  document.getElementById(layer).innerHTML="loading";
              }
          }
          xmlHttp.open("GET",url,true);
          xmlHttp.send(null);
      }
      
      
      function deleteRow(i){
          document.getElementById('myTable').deleteRow(i)
      }
      

      【讨论】:

      • 我无法更改更新方法,因为它已被其他方法使用。请参阅我的问题所附的示例。是否仍然可以使用类似于上述的方法?
      【解决方案8】:

      我会投票支持推荐 jQuery 的其他答案之一,但我还没有足够的分数。

      我认为实现您正在寻找的“更新”的最简单方法是让您的 AJAX 删除返回相关的删除后 HTML,或者您可以使用 jQuery 触发删除然后删除 tr,页面中的 div 等。

      jQuery.post("get_records.php ", { cmd: "delete", pk: 123 }, function() {
          jQuery("tr.row123").remove(); 
      })
      

      【讨论】:

        【解决方案9】:

        我发现在基于 Ajax 的管理页面上执行三种基本操作:更新、删除和追加。这些动作中的每一个都以不同的方式改变 DOM。

        您已经编写了一个可以更新 DOM 中现有 div 的函数,但是如果您想从当您决定要使用 Ajax 添加新记录时,像您在这个问题中所做的 DOM 也不会很好地工作。

        为了正确处理这个问题,您首先需要为输出的每一行分配一个唯一的 id:

        $pk = $row['ARTICLE_NO'];
        
        echo '<tr id=\"article_' . $pk . '\">' . "\n"; 
        
                echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n"; 
        
        echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n"; 
        
        echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['ARTICLE_NAME'].'</a></td>' . "\n"; 
        
        
        echo '<td><a href="#" onclick="deleteRec(\'article_' . $pk .'\', )">'.$row['ARTICLE_NAME'].'</a></td>' . "\n"; 
        
        echo '</tr>' . "\n";
        

        然后你需要创建一个可以删除表格行的删除函数:

        function delete(layer, url) {
            var xmlHttp=GetXmlHttpObject(); //you have this defined elsewhere
        
            if(xmlHttp==null) {
                alert("Your browser is not supported?");
            }
        
            xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
                    if(xmlHttp.responseText == 'result=true') {
                        // Here you remove the appropriate element from the DOM rather than trying to update something within the DOM
                        var row = document.getElementById(layer);
                        row.parentNode.removeChild(row);
                    }
                } else if (xmlHttp.readyState==1 || xmlHttp.readyState=="loading") {
                    document.getElementById(layer).innerHTML="loading";
                }
        
               //etc
            }
        
            xmlHttp.open("GET",url,true);
            xmlHttp.send(null);
        }
        

        然后最后调整你的 deleterec 函数:

        function deleteRec(layer, pk) {
           url = "get_records.php?cmd=deleterec&pk="+pk+"&sid="+Math.random();
           delete(layer, url);
        }
        

        作为最后一点,我必须回应其他人建议使用框架的观点。任何框架的使用,无论是 jQuery、Prototype、Dojo 还是其他,都会带来短期和长期的好处。此外,我永远不会真正使用 GET 来执行这种性质的操作。强制删除元素所需要做的就是点击相应的 URL 并传入相关的文章编号。

        【讨论】:

        • 传递rowid为什么叫layer?后面的代码“层”实际上似乎需要一个层,而不是一个rowid,所以我不确定当传递一个行id时这个函数是如何工作的。
        • 另外,你可以用什么来代替 GET?
        • 发布。每当您要调用修改服务器端数据的函数时,您都应该使用 POST 来传递该信息,因为它更安全。
        猜你喜欢
        • 1970-01-01
        • 2021-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-20
        • 2013-10-27
        • 1970-01-01
        相关资源
        最近更新 更多