2014-02-07 5 views
5

EDIT: Alles funktioniert; Die Stöße funktionieren. Das einzige Problem ist, dass bei jedem Drücken der #load_info div auf leer zurückgesetzt wird. Wie kann ich den ursprünglichen Inhalt innerhalb der div beibehalten, obwohl der Inhalt die aktualisierte Version von sich selbst wäre, wie die XML-Datei erneut verschoben wird.Long Polling zum Aktualisieren von DOM unter Beibehaltung kumulierter Attribute von jQuery

Ich habe ein PHP-Skript für lange Abfrage einer XML-Datei und Codierung als JSON-Array. Es wird vom Frontend mit dem JSON als Parameter aufgerufen.

$filename= dirname(__FILE__)."/people.xml"; 

    $lastmodif = isset($_GET['timestamp'])? $_GET['timestamp']: 0 ; 
    $currentmodif=filemtime($filename); 

    while ($currentmodif <= $lastmodif) { 
     usleep(10000); 
     clearstatcache(); 
     $currentmodif =filemtime($filename); 
    } 

    $response = array(); 
    $xObj = simplexml_load_file($filename); 

    // Loop for #loadMe. 
    foreach($xObj as $person){ 
     $concat_buttons .= "<button class='mybutton' value='" . (string)$person->id . " '> " . (string)$person->fullName . "</button>"; 
    } 

    // Loop for #toadMe. 
    foreach($xObj as $person){ 
     $concat_info .= "<div class='div div_' data-person-id='" . (string)$person->id . "' id='" . (string)$person->id . "'><h1> " . (string)$person->job . "</h1></div>"; 
    } 


    // Output for AJAX. 
    $response['msg']    = $concat_buttons; 
    $response['msg2']    = $concat_info; 
    $response['timestamp']  = $currentmodif; 
    echo json_encode($response); 

Dann habe ich eine jQuery-Skript das JSON-Objekt für Instancing (msg2) für jeden Knoten in ein div Anhängen genannt #load_data. Meine Frage ist warum funktioniert die jQuery unten nicht? Meine Vermutung ist entweder $(window).find funktioniert nicht in der get_person(id) Funktion und/oder meine Funktionen sind außerhalb des Geltungsbereichs mit der Abfrage. Zu beachten, dass PHP und JS zu 100% funktionierten, bevor ich anfing, die Funktionen show_person() und get_person() zu integrieren. Wenn man innerhalb von #load_buttondiv auf eine bestimmte Schaltfläche klickte, wurde ein Teil der Informationsansicht mit einer id umgestellt, die dem Attribut value der Schaltfläche mit .show() entsprach, das ursprünglich verborgen war; dann, wenn eine andere Taste geklickt wurde, würde die alte Information mit versteckt werden und die neuen Daten würden gesehen werden. Dies war meine runde Lösung für die Verwendung von Long-Polling, um DOM-Elemente zu aktualisieren, indem Sie sie alle am Anfang laden, aber wenn eine Information während einer neuen Abfrage angezeigt wird (vartimestamp wird aktualisiert), dann die Elemente im Inneren von #load_info wird vorübergehend aus dem DOM verloren, was zu einem leeren führt, bis die nächste Schaltfläche geklickt wird. Also versuche ich, einige zusätzliche Funktionen hinzuzufügen, um DOM-Daten innerhalb der var$person zu speichern, so dass nach einer Umfrage, was vorher gezeigt wurde, wieder erscheinen würde. Was kann geändert oder hinzugefügt werden, damit dieses jQuery-Skript wie gewünscht funktioniert? Danke im Voraus!

var timestamp=null; 
    function waitForMsg() { 
     $.ajax({ 
      type: "GET", 
      url: "getData.php?timestamp="+timestamp, 
      async: true, 
      cache: false,   
      success: function(data) { 
       var json=eval('('+data+ ')'); 
       if (json['msg'] != "") { 
        $("#load_buttons").empty(); 
        $("#load_buttons").append(json['msg']); 

        // Update any person divs that were already visible. 
        $('#load_info .person').each(function() { 
         // Grabs the ID from data-person-id set earlier. 
         var id = $(this).data('person-id'); 
         show_person(id); 
        }); 

       } 
       timestamp = json["timestamp"]; 
       setTimeout("waitForMsg()",1000); 
      }, 
      error: function(XMLHttpRequest,textStatus,errorThrown) { 
       setTimeout("waitForMsg()",15000); 
      }     
     }); 
    } 

    $(document).on('click', '.mybutton', function() { 
     $('#load_info').empty(); 
     show_person(this.value); 
    }); 

    function show_person(id) { 
     $('#person-detail-' + id).remove(); 
     get_person(id).appendTo('#load_info'); 
    } 

    function get_person(id) { 
     var $person = $(window).find('id:contains(id)'); 

     var $div = $('<div>', { 
      'class': 'person', 
      'data-person-id': id, 
      id: id 
     }); 

     $person.find(h1).text.appendTo($div); 
     return $div; 
    } 
+0

Was ist Ihre Absicht mit '$ (window) .find ('id: enthält (id)');'? – Kyle

+0

@Kyle Kyle, ich versuche, es als Mittel zu verwenden, um eine Variable für die Aufnahme der aktuellen Element (e) im Container # load_info zu erstellen, daher kann die Variable verwendet werden, um das/die Element (e) erneut anzuzeigen wurde/wurden vor dem nächsten Push angezeigt; Wenn etwas vorher angezeigt wurde, klicken Sie auf den Button. – Jim22150

Antwort

1

Ich fand Ihre Frage ziemlich schwierig zu verstehen, aber ich mag eine Herausforderung. Als eine Anmerkung habe ich diesen Code nicht getestet, so dass er debuggt werden müsste.

Nun, wie ich es verstehe, haben Sie eine Reihe von Schaltflächen mit dieser Struktur:

<div id="load_buttons"> 
    // repeater 
    <button class="mybutton" value="$person['id']">$person['fullName']</button> 
    // end repeater 
</div> 

und ein paar Detail divs mit dieser Struktur, die zunächst verborgen sind:

<div id="load_info"> 
    // repeater 
    <div class="div div_" data-person-id="$person['id']" id="$person['id']"> 
    <h1>$person['job']</h1> 
    </div> 
    // end repeater 
</div> 

Und diese sollten bei jeder Umfrage aktualisiert/angehängt werden.

Was möchten Sie erreichen: Wenn auf eine Schaltfläche geklickt wird, werden die zugehörigen Informationen angezeigt. Ich würde Ihren Erfolg Funktion wie folgt tun:

success: function(data) { 
    var json=eval('('+data+ ')'); 
    var $buttons; 
    var $infos; 
    if (json['msg'] != "") { 
     addButtons($(json['msg'])); 
     addInfos($(json['msg2'])); 
    } 
    timestamp = json["timestamp"]; 
    setTimeout("waitForMsg()",1000); 
} 

addButtons = function($buttons){ 
    // loop through the button json data 
    $buttons.each(function(){ 
    // look to see if the button already exists 
    var existing = $('[value='+$(this).attr("value")+']').length; 
    if(!existing){ 
     // if not, add the button and assign a click handler 
     $(this).appendTo('#load_buttons').click(function(){ 
     //hide all the children of info 
     $('#load_info').children().hide(); 
     //show the info based on the button value 
     $('#'+$(this).val).show(); 
     }); 
    } 
    }); 
} 
addInfos = function($infos){ 
    //loop through the info json data 
    $infos.each(function(){ 
    // check to see if an info exists 
    var existing = $('#'+$(this).attr("id")).length; 
    if(!existing){ 
     //if not, add the info to the list and set it to hidden 
     $(this).appendTo('#load_info').hide(); 
    } 
    }); 
} 
+0

das sieht gut aus, aber viel anders als mein Versuch so leid für die späte Antwort. Ich versuche es mit meinem Prototyp zu implementieren; Ich werde einen weiteren Kommentar hinterlassen, der meine Ergebnisse beschreibt. – Jim22150

4

Es sieht aus wie Sie ein Problem zu erzeugen Ihre JSON in dem PHP-Skript haben:

$response['msg'] = $concat; 
$response['msg2'] = $concat2; 

$concat und $concat2 sind nicht überall definiert, meinen Sie $concat_buttons und $concat_info stattdessen verwenden?

$response['msg'] = $concat_buttons; 
$response['msg2'] = $concat_info; 

In Ihrem jQuery verweisen Sie #load_info .person, aber es sieht nicht die divs, die PHP Klasse baut person, die sein könnte, warum Ihre Schleife sie nicht findet.

+0

Vielen Dank für das Aufzeigen. Der Live-Code, den ich testen möchte, hat diesen Fehler jedoch nicht. Ich habe die Variablen für den Frage-Post umbenannt und vergessen, die Anweisungen umzubenennen, auf die Sie hingewiesen haben. Ich habe meine Frage mit Ihrer Fehlerbehebung aktualisiert. Sorry für den Syntaxfehler, aber das Grundproblem bleibt bestehen. Ich habe meine Frage auch neu formuliert, um mehr Sinn zu machen. – Jim22150

Verwandte Themen