数据表只更新行而不重新加载表 [英] Datatables updating only rows without reloading table

查看:229
本文介绍了数据表只更新行而不重新加载表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:
我有一个包含小部件的小型jquery应用程序。这个应用程序有两种类型的小部件,它们是计数器小部件和网格小部件。对于网格小部件,我正在使用 dataTables

我的应用程序基本上连接到服务器并收到诸如窗口小部件名称等各种信息。因此,基于接收的信息,我动态地为每个窗口小部件创建页面。事情现在工作正常,但我面临一点问题。

My app basically connects to a server and recieves various information such as widget names etc. So based on the information received i dynamically create pages for each widget. Things are working fine at the moment but i am facing a little problem.

问题
我现在的问题是使用我的网格小部件利用dataTables api.From从我的服务器我收到格式的网格信息。

Problem The issue i have right now is to do with my grid widgets which utilize dataTables api.From my server I receive the grid information in this format.

//EXAMPLE INPUT
/*
<?xml version="1.0" encoding="UTF-8"?>

<rows>

 <head>
 <column width="55" type="ro" align="left" sort="str">Player</column>
 <column width="55" type="ro" align="left" sort="str">State</column>
 <column width="55" type="ro" align="left" sort="str">Points</column>
 </head>
      <row id="1">
            <cell>Lebron King James</cell>
            <cell>Best Mode</cell>
            <cell>45</cell>
      </row>
</rows>
*/

然后我将其解析为适当的表格式(function createTableStringFromXML),因此使用数据表。

Then i parse it to the appropriate table format (function createTableStringFromXML) so it works with the datatables.

我的表每3秒重新加载一次。所以这是这个问题。

My table is reloading every 3 seconds. So this is the problem.

事件我想要我的表更新我认为重新加载整个表是坏的,因为它不仅看起来很奇怪,但我认为没有必要。我想知道有没有办法,我可以写一些功能,比较旧表与新的更新表,只更新需要更新的行?那么这样的方式整个桌子自己没有加载?

Eventhough i want my table to update i think reloading the entire table is bad because not only does it look weird but i think it is not necessary. I was wondering is there way i can write some function that compares the old table with the new updated table and only updates rows that need update? So this way the entire table it self is not loaded?

我的HTML代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>NBA Fanatico</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="themes/tdMobile.min.css" />
        <link rel="stylesheet" href="themes/jquery.mobile.icons.min.css" />
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile.structure-1.4.0.min.css" />
    <link rel="stylesheet" type="text/css" href="cssfinal/style.css" />


        <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>


    <script src="dhtmxSuite/dhtmlxWindows/codebase/dhtmlxcommon.js" type="text/javascript"></script> 

           <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
       <script src="jquery.ui.touch-punch.min.js"></script>

   <!-- MAIN JS SCRIPT CONTANS CODE FOR COUTNER WIDGETS, TABLES , AJAX REQUEST FOR GETTING DATA-->

     <script src="dynamic.js"></script>



<!-- SCRIPTS FOR DATA TABLES -->

<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css" />



<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>




    </head>
    <body>

    <!-- PAGE 1 -->
        <div data-role="page" data-theme="a" id="page1">
            <!-- <div data-role="header" data-position="fixed">
                <h1></h1>
            </div> -->


            <div data-role="content" data-theme="a">




          <div class="login-box" id="login">



             <div id="loginprompt">
                <div id="header">


            <h3>Basketball Fanatico</h3>

        </div>

                </div>
        <form method="GET">

                <div id="username" data-role="fieldcontain">     
                    <input type="text" name="username" placeholder="Username" />
                </div>
                <div id="password" data-role="fieldcontain">   
                   <input type="password" name="password" id="txtId" placeholder="Password"/>
                </div>
                <div id ="loginbtn">
                    <a data-role="button" id="log" data-theme="a" href="#page2" data-transition="slide">LOGIN</a>
                </div>
            </form>

            <br />


</div>

            </div>


            </div>

        </div>


<!-- PAGE 2 -->

<div data-role="page" id="page2">

  <div data-role ="header" data-position="fixed" data-theme="a"> 
    <a data-iconpos="notext" href="#panel" data-role="button" data-icon="bars"></a>

  <h1 class="ui-title" role="heading">Basketball Fanatico</h1>
    <div class="ui-btn-right"  data-type="horizontal">
      <a data-iconpos="notext" href="#page2" data-role="button" data-icon="home" ></a>
      <a data-iconpos="notext" href="#page1" data-role="button" data-icon="delete" ></a>
    </div>
</div>



            <div data-role="content" id="page2content"> 

                <ul data-role="listview" data-inset="true">
                    <li data-role="list-divider" data-theme="a">WELCOME!</li>
                    <li>Use the menu on the left to navigate <br />and configure the various options.</li>                  
                </ul>


            </div>

        </div>

        <div data-role="panel" id="panel"  data-position="left" data-theme="a" data-display="push">
           <!--  <div> -->
                <div id="nav"><h3>Navigation</h3>


                 <hr>
                <label>

                <input id="chkSort" type="checkbox" checked="true"  />Allow sorting</input>
                </label>
                <hr>
            </div>
            <div id="items" data-role="button">
                <!-- Insert Parsed Widget Names Here -->
                <a href="#page1" data-transition="fade" data-theme="a" data-role="button">LOG OUT</a>
            </div>

        <!-- </div> -->


</div>



    </body>
</html>

我的JS

        var widgetNames = new Array();
        var widgetId = new Array();
        var pageId = ''



        $( document ).on( "pagecreate", function() {
            $( "body > [data-role='panel']" ).panel().enhanceWithin();


              //Format the grid as required
              $('#example2').dataTable( {
                "bPaginate": false,
                "bFilter": true,
                "bAutoWidth": false,
                "oLanguage": { "sSearch": "" } 
               } );

              $('.dataTables_filter input').attr("placeholder", "Search");
              $('.dataTables_filter').css('float','none');    
              $('.dataTables_filter').css('padding-right','0px');    
              $("#example_filter").detach().prependTo('#header1');    

        });

        $(document).on('pagecreate', '#page1', function() {

           // $( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
           //                    pageId = $('body').pagecontainer('getActivePage').prop("id"); 
           //                    alert( "The page id of this page is: " + pageId );
           //                    });


            $("#log").on('click', function(){

                $.ajax({
                    url: "script.login",
                        type: "GET",
                        data: { 'page':'create_user', 'access':'user','username':$("input[name='username']").val(), 'password':$("input[name='password']").val()},
                        dataType: "text",
                        success: function (html) {
                            //console.log(html);


                            widgetNames = new Array();
                            widgetId = new Array();
                            var res = html.match(/insertNewChild(.*);/g);



                            //Get each widget name and ID and assign to values in an array
                            for(var i =0;i<res.length;i++){
                                //alert(res[i]);
                                var temp = res[i].split(',');
                                if(temp.length >= 3){
                                  widgetNames[i] = (temp[2].replace('");','')).replace('"','');
                                  widgetId[i] = temp[1].replace("'","").replace("'","").replace(/ /g,'');
                                }           
                            }

                            var AllWidgets = ''
                            var testwidget = new Array();



                            //Loop through the html returned and get the data relevant to each widget... save in temp array                            
                            var tempWidgetContent = html.match(/w\d+\.isHidden(.*)\(\) == false\)[\s\S]*?catch\(err\)\{ \}/gm);
                            for(var i =0;i<tempWidgetContent.length;i++){
                                  var widgetContent = tempWidgetContent[i].substring(tempWidgetContent[i].indexOf('{')+1);
                                 //alert(widgetContent);

                                 //This alone handles coutners...
                                  testwidget[i] = widgetContent.replace("site +","");

                                  //replace the code for a grids...
                                  if(testwidget[i].indexOf('grid') > 0){

                                    testwidget[i] = CreateGridUpdateFunction(testwidget[i],i);
                                  }


                            }



                            var widgetPart =  new Array();

                            //Assume we have widget names, ids, and loading data in 3 arrays
                            //Loop through and create the necessary page.
                            for(var i = 0; i<widgetNames.length; i++){




                              if(testwidget[i].indexOf('hi') > -1){
                                // alert('WORKING');
                                var pageHeaderPart = "<div data-role= 'page' id='"+widgetId[i]+"' data-pageindex='"+i+"' class='dynPageClass'><div data-role='header' id='header1' data-position='fixed' data-theme='a'><a href='#panel' data-icon='bars' data-iconpos='notext' class='ui-btn-left'></a><a href='#' data-icon='search' id='search' data-iconpos='notext' class='ui-btn-left' style='margin-left: 35px'></a><h1>BASKETBALL FANATICO</h1><a href='#page1' data-icon='delete' data-iconpos='notext' class='ui-btn-right'></a><a href='#page2' data-icon='home' data-iconpos='notext' class='ui-btn-right' style='margin-right: 35px;'></a></div><div data-role='content'>";
                              }

                              else{

                               var pageHeaderPart = "<div data-role='page' id='"+widgetId[i]+"' data-pageindex='"+i+"' class='dynPageClass'><div data-role='header'data-position='fixed' data-theme='a'><a data-iconpos='notext' href='#panel' data-role='button'data-icon='bars'></a><h1 class='ui-title'role='heading'>BASKETBALL FANATICO</h1><div class='ui-btn-right' data-type='horizontal'><a data-iconpos='notext' href='#page2' data-role='button'data-icon='home'style=\" margin-right:5px; \"></a><a data-iconpos='notext' href='#page1' data-role='button'data-icon='delete'></a></div></div><div data-role='content'>";
                              }


                               var pageFooterPart = "</div><div data-role='footer' data-position='fixed'><span class='ui-title'><div id='navigator'></div></span></div></div>";


                               if(testwidget[i].indexOf('hi') > -1){
                                   // alert('i am a grid');

                               var check = "<div data-role='tbcontent'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='a'>"+widgetNames[i]+"";

                               }


                               var check = "<div data-role='content'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='a'>"+widgetNames[i]+"</div>";

                               if(testwidget[i].indexOf('counterValue') > 0){
                                 // alert('i am a counter');

                                  widgetPart[i] = '<DIV style=\" text-align: center; background-color:#EDEDED; padding-bottom: auto;  font-size: 55pt;\" id=widgetContainer_'+widgetId[i]+'></DIV><SCRIPT>' + 'function UpdateWidgetDiv'+widgetId[i]+'() {' + testwidget[i] + '$(\"#widgetContainer_'+widgetId[i]+'").html(counterValue);' + '}' + '</SCRIPT>';




                               }
                               if(testwidget[i].indexOf('hi') > -1){
                                // alert('i am a grid');

                                   widgetPart[i] = '<DIV id=widgetContainer_'+widgetId[i]+'></DIV><SCRIPT>' + 'function UpdateWidgetDiv'+widgetId[i]+'() {' + testwidget[i]  + '}' + '</SCRIPT>';
                               }
                               else {
                                  widgetPart[i] = '<DIV style=\" text-align: center; background-color:#EDEDED; padding-bottom: auto;  font-size: 55pt;\" id=widgetContainer_'+widgetId[i]+'>I dont know what I am</DIV>';
                               }

                               AllWidgets +='<a href="#'+widgetId[i]+'" class="widgetLink" data-theme="b" data-role="button" >'+widgetNames[i]+'</a>';                         

                                             var makePage = $(pageHeaderPart + check + widgetPart[i] + pageFooterPart);

                               makePage.appendTo($.mobile.pageContainer);
                            }
                            $('#items').prepend(AllWidgets).trigger('create');


//Widget Update Function

function UpdateActivePage(){
    //get active page
    pageId = $(":mobile-pagecontainer" ).pagecontainer('getActivePage').prop("id");
    //figure out index
    var idx;
    for (var i=0; i<widgetId.length; i++){
       if (widgetId[i] == pageId){
          idx = i;
          break;
       }
    }

//alert(pageId);
    //run your update
    //alert("RUNNING:");
    eval(testwidget[idx]);
    //alert('Updateing active page');
    $("#widgetContainer_" + pageId).html(counterValue);


        $('#grid_'+idx).dataTable( { 
          "bPaginate": false,
          "bFilter": true,
          "bAutoWidth": false,
          "oLanguage": { "sSearch": "" } 
        } );
       $('.dataTables_filter input').attr("placeholder", "Search");
       $('.dataTables_filter').css('float','none');  
       $('.dataTables_filter').css('padding-right','0px');   
       $("#example_filter").detach().prependTo('#header1');   


}


function CreateGridUpdateFunction(oldUpdatefunction,thisWidgetID)
{




    var updateLines = oldUpdatefunction.split("\n");
    var updateFunctionCode = "";
    for (var i=0; i<updateLines.length;i++)
    {
        if(updateLines[i].indexOf(" var url = ") > 0)
        {

            var updateURL = updateLines[i];
            if(updateURL.indexOf("&windowWidth=") > 0){
                updateURL = updateURL.substr(0,updateURL.lastIndexOf("&windowWidth=")) + "';";

            }

            updateFunctionCode += updateURL;   
            updateFunctionCode += "   var loader = dhtmlxAjax.getSync(url);";   
            updateFunctionCode += "   if(loader.xmlDoc.responseText.length > 0){";

            updateFunctionCode += "     counterValue = createTableStringFromXML(loader.xmlDoc.responseText,"+thisWidgetID+");";
            updateFunctionCode += "   }   ";


        }
    }


    return "var counterValue = \"hi\"; "+updateFunctionCode ; 
}


$(":mobile-pagecontainer" ).on( "pagechange", function()  { UpdateActivePage(); } )



setInterval(UpdateActivePage, 3000);



                        }

                });

            });
        });



//Returns a bool indicated if the (space trimmed) string starts with needle.
function startsWith(searchString,searchVal){
  var search = searchString.trim();
  return search.indexOf(searchVal) >= 0;
}

function createTableStringFromXML(serverXML,thisWidgetID){


  console.log(serverXML);

  var xmlLines = serverXML.split("\n");
  var returnTable = "";


  for (var i=0; i<xmlLines.length;i++)
  {
     if(startsWith(xmlLines[i],"<rows"))
     {
        returnTable += "<table cellpadding=\"2\"  cellspacing=\"2\" border=\"0\" class=\"display\" id=\"grid_"+thisWidgetID+"\" width=\"100%\">";
     }
     else if(startsWith(xmlLines[i],"</rows>"))
     {
        returnTable += "</tbody></table>";
     }
     else if(startsWith(xmlLines[i],"<head>"))
     {
        returnTable += "<thead><tr>";
     }
     else if(startsWith(xmlLines[i],"</head>"))
     {
        returnTable += "</tr></thead><tbody>";
     }
     else if(startsWith(xmlLines[i],"<column"))
     {
        returnTable += "<th>"+xmlLines[i].match(/>(.*?)</i)[1]+"</th>";
     }
     else if(startsWith(xmlLines[i],"<row"))
     {
        returnTable += "<tr>";
     }
     else if(startsWith(xmlLines[i],"</row"))
     {
        returnTable += "</tr>";
     }     
     else if(startsWith(xmlLines[i],"<cell"))
     {
        returnTable += "<td>"+xmlLines[i].match(/>(.*?)</i)[1]+"</td>";
     }


console.log(returnTable);

  }


   return returnTable ;

}

请咨询实现这一点对不起,如果你没有理解我的问题,请再问一次。我只使用HTML和JS几个月,所以我是新的,这也可能是为什么我的问题可能听起来很愚蠢的一些你提前抱歉。对于我可怜的英语,我很抱歉,如果你不明白,请让我知道。谢谢。

Please advice on how to achieve this. I am sorry if you have not understood my question so please ask me again. I am only using HTML and JS for couple of months so i am band new to this and that also might be the reason why my question might sound silly to some of you so sorry in advance. I apologize for my poor english please let me know if you dont understand. Thanks.

推荐答案

每3秒更新一次表可能会导致性能问题,特别是如果你有很多行!

Updating the table every 3 seconds could cause performance issues, especially if you have lots of rows!

如果要这样做,可以遍历更新XML中的行,然后将值写入表中的各个单元格。

If you want to do it, you can iterate through the rows in the update XML and then write the values to the individual cells in the table.


演示

DEMO

在我的示例中,表已经存在行ID作为行元素上的数据属性。我正在按钮点击而不是每3秒更新一次定时器,但解析将是一样的。

In my example, the table is already there with row ids as data attributes on the row element. I am updating once on a button click instead of every 3 seconds on a timer, but the parsing would be the same.

$("#update").on("click", function(){
    var $trows= $('#example tbody tr');       
    var xmlDoc = $.parseXML( xmlstring );
    var $xml = $( xmlDoc );  

    $xml.find("row").each(function(index){            
        var id = $(this).prop("id");            
        var $cells = $(this).find("cell");
        var c1 = $cells.eq(0).text();
        var c2 = $cells.eq(1).text();
        var c3 = $cells.eq(2).text();

        //get row in table with this id
        var $rowtd = $('#example tbody [data-id=' + id + '] td');
        $rowtd.eq(0).text(c1);
        $rowtd.eq(1).text(c2);
        $rowtd.eq(2).text(c3);
    });  
});

代码将XML字符串加载到XmlDocument中,然后从文档创建一个jQuery对象。接下来,我遍历所有名为row的Xml节点获取id和3个单元格文本。然后我在现有表中找到具有相同ID的行,并将文本写入行中的existsind TD。

The code loads the XML string into an XmlDocument and then creates a jQuery object from the document. Next I iterate through all the Xml Nodes called "row" getting the id and the 3 cell texts. Then I find the row in the existing table with the same Id and write the texts into the existind TDs in the row.

您将需要测试此给定的性能您拥有的正常行数和您计划支持的设备类型。

You will need to test the performance of this given the normal number of rows you have and the types of devices you plan to support.

这篇关于数据表只更新行而不重新加载表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆